Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
题目来源:LeetCode>二维数组中的查找
在一个 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
二、思路分析:
- 当看见有二维数组时,直接反应应该是两个for循环,然后挨个进行判断,存在就返回true,不存在就返回false,但是这样做的话,直接让此题失去了考察的意义,显然,这一题不会简单两个for就能直接解决的。
- 观察题目中的矩阵,看得出来从左上角出发,往右边和往下都是递增的,肯定不能直接找到target
- 如果从右下角出发,往上边和往左边都是递减的,也没办法找出targer
- 但是如果从右上角、左下角出发的话,就可以有递增和递减两种选择,利用这一点,可以找到target
三、AC 代码:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int rowLength = matrix.length;
if (rowLength == 0) return false;
int columnLength = matrix[0].length;
int i = 0, j = columnLength - 1;
while ((i >= 0 && i < rowLength) && (j >= 0 && j < columnLength)) {
if (target == matrix[i][j]) {
return true;
}
if (target > matrix[i][j]) {
i++;
continue;
}
if (target < matrix[i][j]) {
j--;
continue;
}
}
return false;
}
}
虽然暴力解法不是最终解,但是还是列一下代码:
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
if(matrix[i][j] == target){
return true;
}
}
}
return false;
}
}
四、总结:
- 站在右上角看。这个矩阵其实就像是一个Binary Search Tree。
- 从矩阵出发,如果从左上角开始找,那么如果当前数比目标值小的话,向下走或者向右走都可以让数变大,方向就不能确定,所以应该找从两个方向走一个是变大的一个变小的位置作为起始位置,比如右上角和左下角。