题目
在一个 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。
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/er…
思路
把这个矩阵从右上角看向左下角,跟二叉搜索树的结构很像。所以可以把这个矩阵近似看成二叉搜索树。这样的思路就很清晰了。
我第一次做没想出来,就直接暴力了,这道题通过后看了下评论区老哥的一句话,恍然大悟,用二叉搜索树的做法,执行用时超越100%的用户了。
这位老哥是这样说的:
提一个不太有人讲的观点,站在右上角看。这个矩阵其实就像是一个Binary Search Tree。然后,聪明的大家应该知道怎么做了。
题解
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
return answer2(matrix, target);
}
// 暴力法
private boolean answer1(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 ||
matrix[0] == null || matrix[0].length == 0)
return false;
List<Integer> numbers = new ArrayList<>(matrix.length * matrix[0].length);
for (int[] row : matrix) {
for (int e : row) {
numbers.add(e);
}
}
Collections.sort(numbers);
return Collections.binarySearch(numbers, target) >= 0;
}
private int xMax;
private int yMax;
// 受到评论区老哥的启发,用二叉树搜索做
private boolean answer2(int[][] matrix, int target) {
if (matrix == null || matrix.length == 0 ||
matrix[0] == null || matrix[0].length == 0)
return false;
xMax = matrix.length;
yMax = matrix[0].length;
int x = 0, y = yMax - 1;
while (checkRange(x,y)) {
if (target < matrix[x][y]) {
// 小于就遍历左子树(当成二叉搜索树来看)
y--;
} else if (target > matrix[x][y]) {
// 大于就遍历右子树
x++;
} else {
return true;
}
}
return false;
}
private boolean checkRange(int x, int y) {
return x >= 0 && y >= 0 && x < xMax && y < yMax;
}
}