当前位置:   article > 正文

leetcode74-搜索二维矩阵(中等难度)_leetcode74移位

leetcode74移位


力扣链接

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

示例 1:
在这里插入图片描述

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
  • 1
  • 2

示例 2:
在这里插入图片描述

输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
  • 1
  • 2

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 100
  • -104 <= matrix[i][j], target <= 104

我的解题思路

这题要实现非常简单,关键就在于如何采取高效的方法去查找二维数组中的目标值。
我写的代码看起来有点复杂,但是效率应该是可以的,类似于一维数组中使用二分法查找目标值。
经过了n次找bug,终于写出来了,但是看了官方的题解,有些地方还是想的复杂了点。

  1. 首先通过[startX,startY],[endX,endY],查找类似于在一维数组中的中心的值的索引,二维数组则用两个索引表示[x,y]
  2. 若是[x,y]处的值刚好为target,则返回true
  3. 如果[startX,startY]与[endX,endY)重合,则返回false, 因为都重合了还不和target相等,肯定不存在了
  4. 如果[x,y]处的值大于target,在左面继续找
    • 此时有一种特殊情况,就是[startX,startY]与[x,y]重合的时候,此时target也必不存在
    • 当y=0
      • 如果x也等于0,则返回false,target必不存在,因为是升序的。
      • 递归查找
    • 递归查找
  5. [x,y]处的值小于target,在右面继续找
    • 如果y = 列长 - 1
      • x = 行长 - 1,则返回false,target不存在,因为升序,此位置已经是最大值了,还是小于target
      • 递归查找
    • 递归查找

代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int i = matrix.length - 1;
        //表示数组的列数
        int j = matrix[0].length - 1;
        return binarySearch(matrix, 0, 0, i, j, target);
    }

    public static boolean binarySearch(int[][] matrix, int startX, int startY, int endX, int endY, int target) {
    	//查找中心位置的索引,即[x,y]
        int row = matrix.length;
        int col = matrix[0].length;
        int location = ((endX * col + endY) + (startX * col + startY)) >> 1;
        int x = location / col;
        int y = location % col;
        if (matrix[x][y] == target) {
            return true;
        }
        if (startX == endX && startY == endY) {
            return false;
        }

        if (matrix[x][y] > target) {
            if (startX == x && startY == y) {
                return false;
            }
            if (y == 0) {
                //[0][0]>target,说明target不存在于数组中
                if (x == 0) {
                    return false;
                }

                return binarySearch(matrix, startX, startY, x - 1, col - 1, target);
            }
            return binarySearch(matrix, startX, startY, x, y - 1, target);
        }
        if (y == col - 1) {
            //[col][col]<target,说明target不存在于数组中
            if (x == row - 1) {
                return false;
            } else {
                return binarySearch(matrix, x + 1, 0, endX, endY, target);
            }
        }
        return binarySearch(matrix, x, y + 1, endX, endY, target);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

时间复杂度

O(log(mn)),m,n分别是行数和列数

官方题解&代码(一次二分查找)

若将矩阵每一行拼接在上一行的末尾,则会得到一个升序数组,我们可以在该数组上二分找到目标元素。

代码实现时,可以二分升序数组的下标,将其映射到原矩阵的行和列上。

代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int low = 0, high = m * n - 1;
        while (low <= high) {
            int mid = (high - low) / 2 + low;
            int x = matrix[mid / n][mid % n];
            if (x < target) {
                low = mid + 1;
            } else if (x > target) {
                high = mid - 1;
            } else {
                return true;
            }
        }
        return false;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

时间复杂度

O(log(mn)),m,n分别是行数和列数

模仿官方题解代码

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int low = 0, high = m * n - 1;
        while (low <= high) {
        	//移位运算符优先级小于+号,所以前面要加括号
            int mid = ((high - low) >> 1) + low;
            int x = matrix[mid / n][mid % n];
            if (x == target) {
                return true;
            } else if (x > target) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        return false;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/459005
推荐阅读
相关标签
  

闽ICP备14008679号