二维数组中的查找
1、参考资料
https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
2、题目要求
题目描述
在一个 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
。
3、代码思路
我们要紧紧抓住这个特点:给定的二维数组具备每行从左到右递增以及每列从上到下递增的特点
第一种方法:从二维数组的右上角开始查找。如果当前元素等于目标值,则返回 true
。如果当前元素大于目标值,则移到左边一列。如果当前元素小于目标值,则移到下边一行。
第二种方法:从二维数组的最下角开始查找。如果当前元素等于目标值,则返回 true
。如果当前元素小于目标值,则移到右边一列。如果当前元素大于目标值,则移到上边一行。
就拿如下矩阵举例说明,我们以 row
和 col
作为二维数组的行、列下标
[
[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]
]
从矩阵的右上角为起点,即 row = 0
,col = 4
,假设目标值为 13
,因为 13 < 15
,所以 col--
,因为 15
的下方的元素都大于 15
,所以我们排除掉了 15
下边的元素
接着 row = 0
,col = 3
,因为 13 > 12
,所以 row++
,因为 12
的左边的元素都小于 12
,所以我们排除掉了 12
左边的元素
以此类推
选左上角,往右走和往下走都增大,不能选
选右下角,往上走和往左走都减小,不能选
选左下角,往右走增大,往上走减小,可选
选右上角,往下走增大,往左走减小,可选
4、代码实现
代码
/**
* @ClassName DindNumberIn2DArrayDemo
* @Description TODO
* @Author Heygo
* @Date 2020/8/29 21:57
* @Version 1.0
*/
public class DindNumberIn2DArrayDemo {
public static void main(String[] args) {
int[][] 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}
};
boolean exist = findNumberIn2DArray(matrix, 12);
System.out.println(exist);
}
public static boolean findNumberIn2DArray(int[][] matrix, int target) {
// Guard Safe
if (matrix.length == 0) {
return false;
}
// 起始坐标为右上角
int row = 0;
int col = matrix[0].length - 1;
// 从数组的右上角向左下角搜索
while (row < matrix.length && col >= 0) {
if (matrix[row][col] > target) { // 如果当前位置的元素 > 目标值,col--
col--;
} else if (matrix[row][col] < target) { // 如果当前位置的元素 < 目标值,row++
row++;
} else { // 否则,证明找到了目标值,返回 true,表示找到目标元素
return true;
}
}
// 遍历完后走没有找到,则证明数组中没有此元素
return false;
}
}
时间复杂度:O(n+m)
,访问到的下标的行最多增加 n
次,列最多减少 m
次,因此循环体最多执行 n + m
次。