题目描述
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
暴力:一个一个元素找
逐行进行 二分查找
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
for (int i = 0; i < matrix.length; i++) {
if (binarySearch(matrix[i], target) != -1) {
return true;
}
}
return false;
}
public int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
System.out.println("right = " + right);
while (left <= right) {
int mid = left + (right - left) / 2;
System.out.println("mid = " + mid);
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
由于本题说了,每行的第一个整数大于前一行的最后一个整数。 所以,查找 “行” 的操作,也可以使用 二分查找
分 2 次进行二分查找:
行
;找到最后一个满足 martix[i][0] <= target 的行号,最终 即为 right 对应的行号
注意:当 right == -1 时,则说明 target < matrix[0][0],此时 matrix 中肯定不存在 target。此时,需要单独 处理,防止 数组越界。 ⭐️
列
,再进行一次 二分查找class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
// 1、第一次二分:找 行
// 找到最后一个满足 martix[i][0] <= target 的行号,最终 即为 right 对应的行号
int left = 0;
int right = matrix.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (matrix[mid][0] > target) {
right = mid - 1;
} else if (matrix[mid][0] < target) {
left = mid + 1;
} else {
right = mid;
break;
}
}
System.out.println("left = " + left);
System.out.println("right = " + right);
// 没有找到满足条件的行,即 right < 0(right = -1)时,则说明 target < matrix[0][0],此时 matrix 中肯定不存在 target。
if (right < 0) return false;
// 当 “行” 的第一个元素就是 target 时,则不必再进行第二次 二分查找
if (matrix[right][0] == target) return true;
// 2、第二次 二分:找列
System.out.println(binarySearch(matrix[right], target));
return binarySearch(matrix[right], target) != -1;
}
public int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
可以把整个矩阵看成一颗 以右上角元素为 root 的 BST:
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int c = matrix[0].length - 1;
int r = 0;
while (c >= 0 && r < matrix.length) {
if (matrix[r][c] > target) {
c--;
} else if (matrix[r][c] < target) {
r++;
} else {
return true;
}
}
return false;
}
}
题目描述
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
这里说下,本题大致和 74. 搜索二维矩阵 一样。
但是,二分查找解法 略有不同。
这里只讲 二分查找 注意事项
由于 74. 搜索二维矩阵,每行的第一个整数大于前一行的最后一个整数。 所以,才可以分 2 次 二分查找,分别找 “行” 和 “列”。
但是,本题 每列的元素从上到下升序排列。所以,只能分别 对每行 进行 二分查找,不能 用二分查找 “行”。
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int r = 0;
int c = matrix[0].length - 1;
while (r < m && c >= 0) {
if (matrix[r][c] > target) { // 向左
c--;
} else if (matrix[r][c] < target) { // 向右
r++;
} else {
return true;
}
}
return false;
}
}
见 上题 74. 搜索二维矩阵 中 BST 解法