题目描述: 给你一个满足下述两条属性的
m x n
整数矩阵:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数
target
,如果target
在矩阵中,返回true
;否则,返回false
。示例 1:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出:true
示例 2:
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-10^4 <= matrix[i][j], target <= 10^4
二分思路:
-
二分查找:使用
left
和right
两个指针表示搜索区间,初始值分别为 0 和m * n - 1
。 -
在循环中,计算中间索引
mid
。然后使用公式x = mid / n
和y = mid % n
++将一维索引转换回二维坐标。++ -
比较矩阵中位置
(x, y)
的值与目标值target
的大小关系:- 如果相等,说明找到了目标值,返回
true
。 - 如果矩阵中的值小于目标值,说明目标值在右半部分,将
left
指针移到mid + 1
。 - 如果矩阵中的值大于目标值,说明目标值在左半部分,将
right
指针移到mid - 1
。
- 如果相等,说明找到了目标值,返回
-
如果在循环结束时仍未找到目标值,说明不存在,返回
false
。
关键点是进行二分查找。这样可以在 O(log(m*n)) 的时间复杂度内完成搜索,相比直接遍历整个矩阵的方法效率要高。利用了矩阵是有序排列的这一特性,通过二分查找的方式快速定位目标值的位置,从而提高了搜索效率。
java
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
if (target < matrix[0][0] || target > matrix[m - 1][n - 1]) {
return false;
}
int left = 0, right = m * n - 1;
int mid = 0;
while (left <= right) {
mid = (left + right) / 2;
int x = mid / n;
int y = mid % n;
if (matrix[x][y] == target) {
return true;
} else if (matrix[x][y] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}
}