方法三(最好的):TC为O(logmn)的解法,把矩阵当作一个一维有序数组来二分查找
- 充分利用题目给定的矩阵特性。
- 关键在于一维二维坐标的转化。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int left = 0, right = m * n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int i = mid / n, j = mid % n; // 二维坐标转为一维
if (matrix[i][j] == target) {
return true;
} else if (matrix[i][j] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return false;
}
}
方法二:TC为O(logm + logn)的解法,行、列分别二分查找
思路:逐渐缩小要查找的tar的范围。
- 对列尾元素进行二分,以确定接下来要搜索的行。
- 在找出来的行中再二分。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix[0].length;
int n = matrix.length;
int row = Integer.MIN_VALUE;//待找的那一行
//二分查找,确定下一步要查找的行
int low1 = 0;
int high1 = n - 1;
while (low1 <= high1) {
int mid = low1 + (high1 - low1) / 2;
if (matrix[mid][m - 1] == target || matrix[mid][0] == target) {
return true;
} else if (matrix[mid][m - 1] > target && matrix[mid][0] < target) {
row = mid;//某一行中,tar小于最后一个数,大于第一个数,找到那一行了
break;
} else if (matrix[mid][m - 1] < target) {
low1 = mid + 1;
} else {
high1 = mid - 1;
}
}
//没找到对应的行,直接false
if (row == Integer.MIN_VALUE) {
return false;
}
//在具体的行中再二分查找target
int low2 = 0;
int high2 = m - 1;
while (low2 <= high2) {
int mid = low2 + (high2 - low2) / 2;
if (matrix[row][mid] == target) {
return true;
} else if (matrix[row][mid] < target) {
low2 = mid + 1;
} else {
high2 = mid - 1;
}
}
return false;
}
}
- 典型错误: 忘了break造成死循环
暴力法:TC为O(mn)
方法一:TC为O(m + n)的解法
思路:逐渐缩小要查找的tar的范围。
- 先线性遍历列的头元素/尾元素,以确定接下来要搜索的行。
- 在找出来的行中搜索。
// TC为 O(m + n)解法
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix[0].length;
int n = matrix.length;
if (target < matrix[0][0] || target > matrix[n - 1][m - 1]) {
return false;
}
//遍历每行头元素,确定下一步要遍历的行。
int i = 0;
while (i < n) {//这里选的时头元素,不太好,得特殊处理最后一行。
if (i == n - 1 && target >= matrix[i][0]) {
break;
} else if (target >= matrix[i][0] && target < matrix[i + 1][0]) {
break;
}
i++;
}
//遍历找出的那一行。
for (int j = 0; j < m; j++) {
if (matrix[i][j] == target) {
return true;
}
}
return false;
}
}