Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
Consider the following matrix:
[ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ]
Given target = 3
, return true
.
题意是如果在m x n 的矩阵中找到目标值,则返回true,否则返回false。
提供两种思路,均为1ms。
开始思路:
- 确定矩阵的维度,即m和n的值
- 在第一列数值上进行二分查找,确定所在行(经过推算发现目标行始终在尾指针erows停留位置,当erows小于0时,目标行在头指针srows行)
- 在该行再次进行二分查找
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int rows = matrix.length;
int cols = matrix[0].length;
int srows = 0;
int erows = rows - 1;
int scols = 0;
int ecols = cols - 1;
while (srows <= erows) { // 寻找目标行
int rindex = (srows + erows) / 2;
if (matrix[rindex][0] < target) {
srows = rindex + 1;
} else if (matrix[rindex][0] > target) {
erows = rindex - 1;
} else {
return true;
}
}
if (erows < 0) {
erows = srows;
}
while (scols <= ecols) { // 在目标行进行二分查找
int cindex = (scols + ecols) / 2;
if (matrix[erows][cindex] < target) {
scols = cindex + 1;
} else if (matrix[erows][cindex] > target) {
ecols = cindex - 1;
} else {
return true;
}
}
return false;
}
}
后来在discuss中看到另一种更简单的解法
- 将矩阵看做已经排好序的list
- 对list用二分查找法,通过mid值,可以找出对应在矩阵中的值
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix == null){
return false;
}
int rows = matrix.length;
int cols = matrix[0].length;
int start = 0;
int end = rows * cols - 1;
while(start <= end){
int mid = (start + end) / 2;
// 确定mid表示的位置
int r = mid / cols; // 行
int c = mid % cols; // 列
int value = matrix[r][c];
if (value < target){
start = mid + 1;
}else if(value > target){
end = mid - 1;
}else{
return true;
}
}
return false;
}
}