编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
来源:力扣(LeetCode)
240. 搜索二维矩阵 II
此题有三种方法解题:
1.暴力解法O(n^2)
2.因为是有序的,所以可以用二分搜索
3.空间缩减法(此方法在我之前的发布的博客中用了很多次)
4.利用矩阵的性质*(时间复杂度:O(n+m))此方法我们来实现一下
首先,我们初始化一个指向矩阵左下角的 (row,col)指针。然后,直到找到目标并返回 true(或者指针指向矩阵维度之外的 (row,col) 为止,我们执行以下操作:如果当前指向的值大于目标值,则可以 “向上” 移动一行。 否则,如果当前指向的值小于目标值,则可以移动一列。不难理解为什么这样做永远不会删减正确的答案;因为行是从左到右排序的,所以我们知道当前值右侧的每个值都较大。 因此,如果当前值已经大于目标值,我们知道它右边的每个值会比较大。也可以对列进行非常类似的论证,因此这种搜索方式将始终在矩阵中找到目标(如果存在)。
问题来了 为什么要先选定左下角的而不选左上角 右下角呢?
因为,我们要进行搜索就要有减有增:
-
选左上角,往右走和往下走都增大,不能选
- 选右下角,往上走和往左走都减小,不能选
- 选左下角,往右走增大,往上走减小,可选
- 选右上角,往下走增大,往左走减小,可选
所以四种角度两种可选 我们选的左下角 来实现
class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null||matrix.length == 0){ return false; } int m = matrix.length - 1, n = 0; while(m >= 0 && n < matrix[0].length){ if(matrix[m][n] == target){ return true; }else if(matrix[m][n] < target){ n++; }else{ m--; } } return false; } }
执行用时: 6 ms
内存消耗: 44 MB