一、题目描述
给你一个满足下述两条属性的 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
二、解题思路
1. 将二维数组的行和列转换为一维数组的索引。假设当前索引为index
,行数为m
,列数为n
,则可以通过index / n
得到行号,通过index % n
得到列号。
2. 执行二分查找,比较target
与矩阵中对应位置的元素值。
- 如果找到
target
,则返回true
。 - 如果
target
小于当前元素,则移动右边界。 - 如果
target
大于当前元素,则移动左边界。
3. 如果二分查找结束仍未找到target
,则返回false
。
三、具体代码
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int left = 0, right = m * n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int row = mid / n;
int col = mid % n;
if (matrix[row][col] == target) {
return true;
} else if (matrix[row][col] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return false;
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 该算法使用二分查找,每次迭代都将搜索范围减半。
- 最坏情况下,需要进行的迭代次数是 O(log(mn)),其中 m 是矩阵的行数,n 是矩阵的列数。
- 每次迭代中,我们只进行常数时间的操作,因此每次迭代的时间复杂度是 O(1)。
- 因此,总的时间复杂度是 O(log(mn))。
2. 空间复杂度
- 该算法只使用了几个额外的变量(left, right, mid, row, col),它们使用的空间是常数的。
- 因此,算法的空间复杂度是 O(1),即常数空间复杂度。
五、总结知识点
-
二分查找算法:这是一种在有序数组中查找特定元素的高效算法,通过不断将搜索范围减半来快速定位元素。
-
二维数组与一维数组的转换:代码中将二维数组的行和列转换为一维数组的索引,通过计算
mid / n
得到行号,mid % n
得到列号,从而在一维数组中模拟二维数组的访问。 -
整数除法和取余运算:在Java中,
%
表示取余运算。这些运算符用于从一维索引计算二维坐标。 -
循环和条件语句:代码中使用
while
循环进行迭代,并使用if-else
语句根据不同条件执行不同的逻辑。
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。