题目
在一个 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
解题思路
1.题目要求我们判断数组中是否含有目标数,我们可以采用两个for循环去遍历数组进行判断,但是其实我们在认真读题后会发现还有一种更高效的方法。
2.题目告诉我们每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。
举个例子:
我们可以看到下面的数比上面的数大,右面的数比左面的数大。那我们可以从左下角进行查找,也就是从这个 18 开始,
18是大于 5 的,那么因为18右面的数比18还要大,那么数字 5 必然不可能在 18 的右面,我们就标红右面的数,代表 5 不可能出现的区域,
这时 5 只可能出现在18的上面,那我们就让行的下标减 1,
此时指向的是数字 10,10 还是大于 5,那 5 也不可能出现在 10 的右面,我们继续将行的下标减1
当指向的数字是 3 是,3 小于 5了 ,那么 5 可会出现在 3 这一行,这时我们就要将列的下标加1,
然后就指向了 6,此时 6 是 大于 5 的 所以 5不可能出现在 6 的后面,我们只能将行的下标减 1,
此时指向的数字刚好是 5,等于我们的目标数字,也就表示我们找到了,返回true即可。
3.我们先设置两个变量 cols 和 rows ,来存储我们二维数组行的数量和列的数量,然后再设置两个变量 col 和 row 储存我们在遍历数组时元素的下标,因为我们是从左下角开始遍历,所以要让col = cols - 1,row = 0;也就是指向左下角的第一个元素。
4.然后我们就用while循环进行遍历,当target 大于我们的当前元素时,我们就让 列下标加 1,若target 小于我们的当前元素时,我们就让行下标减 1,如果两个条件都不满足则说明找到了与target相等的元素。若while()循环结束还没有返回,则代表数组中没有 target 元素,我们就返回 false。
代码实现
class Solution {public boolean findNumberIn2DArray(int[][] matrix, int target) {if(matrix == null || matrix.length <= 0 || matrix[0].length <= 0){return false;}int cols = matrix.length;int rows = matrix[0].length;int col = cols - 1;int row = 0;while(col >= 0 && row < rows ){if(target > matrix[col][row]){row++;}else if(target < matrix[col][row]){col--;}else{return true;}}return false;}
}
测试结果