力扣-搜索二维矩阵

题目

74. 搜索二维矩阵

这道题和在一维数组中查找目标值很像,不过这里的数组变成了二维数组。

在解这道题之前先讲一下怎么在升序一维数组里面用二分查找法找不大于某个目标值(target)的最大索引。例如在数组nums = {1, 3, 5, 7, 9}里面要查找目标值 target = 6,应返回的索引为 2。

java 复制代码
// 查找 nums 中小于等于 target 的最大下标,例如当 nums = {1, 3, 5, 7}, target = 4 时,要返回的坐标为1
    public int findRow (int[] nums, int target){
        int left = 0, right = nums.length - 1;
        // maxIndex 用于保存最终要返回的索引值。
        int maxIndex =  -1;
        int mid = -1;
        while (left < right){
            mid = left + (right - left + 1) / 2;
            if (nums[mid] <= target){
                maxIndex = mid;
                left = mid + 1;
            }
            else {
                right = mid - 1;
            }
        }

        return maxIndex;
    }

思路

因为该二维数组中每行元素都为升序,每列元素也都为升序,因此可以通过两次二分查找来求解。第一次二分法找到对应的行的位置,第二次二分查找找到对应列的位置。

java 复制代码
public boolean searchMatrix(int[][] matrix, int target) {
        boolean flag = false;

        // 边界条件
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }

        int row = matrix.length, col = matrix[0].length;

        // 找行的位置
        int left = 0, right = row - 1;
        // 保存要找的元素在哪一行
        int maxRowIndex = -1;
        int mid = 0;
        while (left <= right) {
            mid = left + (right - left) / 2;
            // 找到
            if (matrix[mid][0] <= target){
                maxRowIndex = mid;
                left = mid + 1;
            }
            else {
                right = mid - 1;
            }
        }

        // 找列的位置
        if (maxRowIndex == -1) {
            return false;
        }
        else{
            int leftCol = 0, rightCol = col - 1;
            int midCol = 0;
            while (leftCol <= rightCol){
                midCol = leftCol + (rightCol - leftCol) / 2;
                if (matrix[maxRowIndex][midCol] == target) {
                    flag = true;
                    break;
                }
                else if (matrix[maxRowIndex][midCol] < target){
                    leftCol = midCol + 1;
                }
                else {
                    rightCol = midCol - 1;
                }
            }
        }

        // 找列的位置
        return flag;
    }

将代码封装一下。

java 复制代码
public boolean searchMatrix(int[][] matrix, int target) {
        boolean flag = false;

        // 边界条件
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }

        int maxIndex = searchRow(matrix, target);
        if (maxIndex == -1) {
            return false;
        }
        return searchCol(matrix, target, maxIndex);

    }

  // 寻找对应行的位置
 public int searchRow (int[][] nums, int target){
      int rows = nums.length, cols = nums[0].length;

      int left = 0, right = rows - 1;
      int mid = -1;
      int maxIndex = -1;
      while (left <= right){
          mid = left + (right - left) / 2;
          if (nums[mid][0] <= target){
              maxIndex = mid;
              left = mid + 1;
          }
          else {
              right = mid - 1;
          }
      }

      return maxIndex;
 }

 // 在每一行中查找对应列的位置
 public boolean searchCol (int[][] nums, int target, int maxIndex){
      int left = 0, right = nums[0].length - 1;
      int mid = -1;
      while (left <= right){
          mid = left + (right - left) / 2;
          if (nums[maxIndex][mid] == target){
              return true;
          }
          else if (nums[maxIndex][mid] < target){
              left = mid + 1;
          }
          else {
              right = mid - 1;
          }
      }

      return false;
 }

时空复杂度

时间复杂度分析:

searchMatrix方法首先检查边界条件,这是一个常数时间的操作,所以时间复杂度为O(1)。

searchRow方法使用了二分查找来确定目标值可能存在的最大行索引。在最坏情况下,需要遍历所有的行来确定最大行索引,但由于使用了二分查找,所以每次比较都可以将搜索范围减半。因此,时间复杂度为O(log m),其中m是矩阵的行数。

searchCol方法也在一个特定的行中使用二分查找来搜索目标值。同样地,时间复杂度为O(log n),其中n是矩阵的列数。

因此,整个searchMatrix方法的时间复杂度是O(log m + log n),可以简化为O(log(mn)),其中mn是矩阵中的元素总数。

空间复杂度分析:

这段代码没有使用额外的数据结构来存储中间结果,除了几个变量(如left、right、mid、maxIndex等)来辅助二分查找过程。

这些变量都是局部变量,并且它们的数量不随输入规模的增长而增长。

因此,空间复杂度为O(1),即常数空间复杂度。

总结:

时间复杂度:O(log(mn)),其中mn是矩阵中的元素总数。

空间复杂度:O(1)。

相关推荐
jktantan38 分钟前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·后端·算法·spring cloud·系统架构
Dream it possible!13 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊14 小时前
算法之双指针系列(一)
算法·leetcode
十二14 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
小此方15 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi16 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
D e re k ZH16 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
Pniubi16 小时前
力扣438.找到字符串中所有字母异位词
算法·leetcode·职场和发展
東隅已逝,桑榆非晚19 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
Eyfcom19 小时前
〖物联网终端实战 01〗UWB 室内高精度定位:仓储 AGV 与人员的厘米级轨迹追踪
物联网·算法·物流系统·快递系统·跨境物流快递系统·物联网终端实战