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.
For example,
Consider the following matrix:
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
Given target = 3, return true.
題意:給定一個矩陣,每一行都是遞增的,每行行首大于上一行行尾。在矩陣中找一個元素,是否能找到?
思路:首先,自己的思路是先找到元素所在的行,可以通過判斷元素和行首行尾的關系確定;然后,在找到的行內用二分法搜索,時間復雜度row + log(col)。
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return false;
}
int m = matrix.length, n = matrix[0].length;
int row = -1;
for (int i = 0; i < m; i++) {
if (target >= matrix[i][0] && target <= matrix[i][n-1]) {
row = i;
break;
}
}
if (row == -1) {
return false;
}
int left = 0, right = n - 1;
while (left + 1 < right) {
int mid = left + (right - left) / 2;
if (matrix[row][mid] == target) {
return true;
} else if (matrix[row][mid] < target) {
left = mid;
} else {
right = mid;
}
}
if (matrix[row][left] == target || matrix[row][right] == target) {
return true;
}
return false;
}
查看discuss更好的思路。其實根絕這個二維矩陣的特性,這個二維矩陣可以看做一個一維遞增的數組,所以可以直接在這個矩陣中用二分搜索。
public boolean searchMatrix(int[][] matrix, int target) {
int row_num = matrix.length;
int col_num = matrix[0].length;
int begin = 0, end = row_num * col_num - 1;
while(begin <= end){
int mid = (begin + end) / 2;
int mid_value = matrix[mid/col_num][mid%col_num];
if( mid_value == target){
return true;
}else if(mid_value < target){
//Should move a bit further, otherwise dead loop.
begin = mid+1;
}else{
end = mid-1;
}
}
return false;
}