064搜索二维矩阵

搜索二维矩阵

题目链接:https://leetcode.cn/problems/search-a-2d-matrix/description/?envType=study-plan-v2\&envId=top-100-liked

我的解答:

复制代码
public boolean searchMatrix(int[][] matrix, int target) {
    int m = matrix.length, n = matrix[0].length;
    int l = 0, r = m - 1;
    int row = 0;
    //找到target可能所在的行
    while(l <= r){
        int mid = l + ((r - l) >>1);
        if(matrix[mid][0] <= target){
            l = mid + 1;
            row = mid;
        }
        else{
            r = mid - 1;
        }
    }
    l = 0;
    r = n-1;
    int col = 0;
    //在row行上查找target
    while(l <= r){
        int mid = l + ((r - l) >>1);
        if(matrix[row][mid] <= target){
            l = mid + 1;
            col = mid;
        }
        else{
            r = mid - 1;
        }
    }
    return matrix[row][col] == target;
}

分析:代码的时间复杂度为O(logm + logn) = O(logmn),空间复杂度为O(1)。解题思路:两次二分查找,先对二维矩阵的第一列进行一次二分查找,找到最后一个第一个数字小于等于target的行,然后在这行上再进行一次二分查找,寻找是否存在target。

看了官方题解后的解答:

复制代码
//方法一:两次二分查找
//时间复杂度:O(logm+logn)=O(logmn)
//空间复杂度:O(1)
public boolean searchMatrix(int[][] matrix, int target) {
    int rowIndex = binarySearchFirstColumn(matrix, target);
    if(rowIndex < 0){
        return false;
    }
    return binarySearchRow(matrix[rowIndex], target);
}
public int binarySearchFirstColumn(int[][] matrix, int target){
    int l = -1, r = matrix.length - 1;
    while(l < r){
        int mid = l + ((r - l + 1) >> 1);//为什么r-l还要加一?防止l = -1 且r = 0时的越界情况
        if(matrix[mid][0] <= target){
            l = mid;
        }
        else{
            r = mid - 1;
        }
    }
    return l;
}
public boolean binarySearchRow(int[] row, int target){
    int l = 0, r = row.length - 1;
    while(l <= r){
        int mid = l + ((r - l) >> 1);
        if(row[mid] == target){
            return true;
        }
        else if(row[mid] < target){
            l = mid + 1;
        }
        else{
            r = mid - 1;
        }
    }
    return false;
}

//方法二:一次二分查找
//时间复杂度:O(logmn)
//空间复杂度:O(1)
public boolean searchMatrix(int[][] matrix, int target) {
    int m = matrix.length, n = matrix[0].length;
    int l = 0, r = m * n - 1;
    while(l <= r){
        int mid = l + ((r - l) >> 1);
        int x = matrix[mid / n][mid % n];
        if(x == target){
            return true;
        }
        else if(x < target){
            l = mid + 1;
        }
        else{
            r = mid - 1;
        }
    }
    return false;
}

分析:

​ 1、方法一的解题思路与我的解答思路一致,只是实现上所有区别,具体区别请看代码。对于此方法,尤其要注意边界情况。

​ 2、方法二的解题思路:根据题目,我们可以想象将每一行都拼接在上一行的末尾,这样我们就得到了一个一维的升序数组,我们可以在该数组上二分查找目标元素。代码实现时,可以二分升序数组的下标,将其映射到原矩阵的行和列上。

总结

  • 本题主要有两种方法解题,分别为两次二分查找、一次二分查找。主要还是需要掌握二分查找,并仔细分析边界情况。
相关推荐
开开心心就好1 分钟前
安卓PDF处理工具,免费无广告零弹窗
android·服务器·开发语言·算法·pdf·ocr
zyl76516 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖20 小时前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌20 小时前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
OPEN-F20 小时前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_3077791320 小时前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
tomwang032220 小时前
路径优化建模、优化算法分类及工程化小结
算法·数学建模·分类
小羊没烦恼!20 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp
2501_9269783321 小时前
人机通信协议--人和机器之间的交互想象
人工智能·经验分享·算法·ai写作
行者全栈架构师21 小时前
【鸿蒙心迹】互动卡片全链路——把核心功能放到桌面(FormKit 实战)(HarmonyOS 7.x)
前端·算法·架构