240. 搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例 1:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true
示例 2:
输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20
输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= n, m <= 300
-109 <= matrix[i][j] <= 109
每行的所有元素从左到右升序排列
每列的所有元素从上到下升序排列
-109 <= target <= 109
解题
方法一:从右上角开始比大小
因为每行的所有元素从左到右升序排列、每列的所有元素从上到下升序排列,所以我们从右上角的数 (记为z) 开始和 target比较大小。
- 如果z > target,列数减1
- 如果z < target,行数加1
- 相等返回true
// 时间O(m+n),(行+列), 空间O(1)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int row = matrix.length;
int col = matrix[0].length;
// x为行,y为列,我们从左上角开始,所以x,y有以下初始值
int x = 0;
int y = col-1;
while(x < row && y >= 0) {
if (matrix[x][y] > target) {
y--;
} else if(matrix[x][y] < target){
x++;
} else{
return true;
}
}
return false;
}
}
方法二:每行二分搜索
每行进行二分搜索,时间O(mlogn)(m为行数,n为列数),空间O(1)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
for (int[] row : matrix) {
//二分搜索,返回下标,如果-1,表明没有
int index = search(row, target);
if (index >= 0) {
return true;
}
}
return false;
}
private int search(int[] row, int target) {
int left = 0;
int right = row.length - 1;
while (left <= right) {
int mid = (right - left) / 2 + left;
if (row[mid] == target) {
return mid;
} else if (row[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
}