240. 搜索二维矩阵 II
难度中等
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例:
现有矩阵 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
。
给定 target = 20
,返回 false
。
思路分析:
这道题比较容易想到的是还继续利用矩阵中的行和列有序的特性,使用二分查找法。思路不止一种,我也尝试写过,后来发现:编写二分查找法要考虑的边界问题比较多,如果对二分查找掌握得不熟练,很可能会出错。
下面介绍的这个方法,我认为是最优解,虽然它的时间复杂度并不是最优。
- 如果我们要用二分查找法,可以发现,如果一行的开头那个元素就比目标元素大,那么这一行的所有元素,以及行号大于这一行的元素都不在考虑的范围内。
- 我们首先尝试从左上角开始走,发现横着走数值增大,竖着走数值也增大,目标数值这在两个方向上都有可能存在。那如果我们从右上角或者左下角除法,找目标元素,那就不一样了,于是有了下面的“排除法”。
方法一:减而治之
- 1、如果选择左下角为起点,以下展示了“减治”的过程。
总结出“搜索”的规律是:
如果当前数比目标元素小,当前列就不可能存在目标值,“指针”就向右移一格(纵坐标加 1);
如果当前数比目标元素大,当前行就不可能存在目标值,“指针”就向上移一格(横坐标减 1)。
在编码的过程中要注意数组下标越界的问题。
参考代码 1:
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int rows = matrix.length;
if (rows == 0) {
return false;
}
int cols = matrix[0].length;
if (cols == 0) {
return false;
}
// 起点:左下角
int x = rows - 1;
int y = 0;
// 不越界的条件是:行大于等于 0,列小于等于 cols - 1
while (x >= 0 && y < cols) {
// 打开注释,可以用于调试的代码
// System.out.println("沿途走过的数字:" + matrix[x][y]);
if (matrix[x][y]