题目
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例:
现有矩阵 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。
限制:
0 <= n <= 1000
0 <= m <= 1000
思路
主要分为几个思考方向:
- 暴力遍历
直接对二维数组matrix[][]进行遍历,如果matrix[i][j] == target,就return true;否则,在退出便利的循环以后,return false;(此时表明:二维数组中不包含该target)
时间复杂度:O(nm)
- 线性查找
因为二维数组的分布规律为:每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
== >
可以从二维数组的左下角或右上角进行分析。
假设现在从右上角进行分析:
对于右上角的元素matrix[0][m-1],与target之间的关系分为三种:>、<、==
(1)如果 matrix[0][m-1] > target,因为每一列都按照从上到下递增的顺序,所以该列的所有元素都比target大,舍弃该列的所有元素;
(2)如果 matrix[0][m-1] < target,因为每一行都按照从左到右递增的顺序,所以该行的所有元素都比target小,舍弃该行的所有元素;
(3)如果 matrix[0][m-1] == target,则,直接return true;
---->将上面的判断过程写进一个循环里边,循环的判断条件为:
while(row <= n-1 && col >= 0)
其中,row的初始值为0;col的初始值为m-1。
----
时间复杂度:O(n + m) 。最多循环n + m次。因为最坏的情况就是最后才找到。
空间复杂度:O(1)。因为两个索引指针需要常数阶的额外空间。 - 二叉搜索树【二叉排序树】
将矩阵逆时针旋转 45° ,并将其转化为图形式,发现其类似于 二叉搜索树 ,即对于每个元素,其左分支元素更小、右分支元素更大。因此,通过从 “根节点” 开始搜索,遇到比 target 大的元素就向左,反之向右,即可找到目标值 target 。
“根节点” 对应的是矩阵的 “左下角” 和 “右上角” 元素,本文称之为 标志数 ,以 matrix 中的 左下角元素 为标志数 flag ,则有:
(1)若 flag > target ,则 target 一定在 flag 所在 行的上方 ,即 flag 所在行可被消去。
(2)若 flag < target ,则 target 一定在 flag 所在 列的右方 ,即 flag 所在列可被消去。
实际上,实现起来,跟上边的“线性查找”是一样的!!!
时间复杂度:O(n + m) 。最多循环n + m次。因为最坏的情况就是最后才找到。
空间复杂度:O(1)。因为两个索引指针需要常数阶的额外空间。
代码实现
1、 暴力遍历
略
2、 线性查找(实现的代码与“3、”的一样)
3、 二叉搜索树【二叉排序树】
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//如果该数组为空,或该数组不含有元素
if(matrix == null || matrix.length == 0){
return false;
}
// int n = matrix.length;
int row = 0;//行的索引
int col = matrix[0].length - 1;//列的索引
while(row <= matrix.length-1 && col >= 0) {//matrix中的元素还没有判断完
if(matrix[row][col] > target){
//target比该元素小,舍弃该列的所有元素
col -= 1;
} else if(matrix[row][col] < target){
//target比该元素大,舍弃该行的所有元素
row += 1;
} else {
//找到了!!!
return true;
}
}
return false;
}
}
学习:
当需要解决一个复杂问题时,一个很有效的办法就是:从一个具体的问题入手,通过分析简单具体的例子,试图寻找普遍的规律。
静下心来,动起手来,不要空想;
将所给的题干,结合具体的实例走一遍
==>会有意想不到的收获!!!!!!