题目描述 在一个 m * n
的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例: 现有矩阵 matrix 如下:
1 2 3 4 5 6 7 [ [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 <= m <= 1000
0 <= n <= 1000
题目链接 Leetcode
题目解答 解法一 暴力查找,即遍历数组中的每一个元素,如果元素的值与target
相等,则返回true
,否则返回false
。
时间复杂度:$O(mn)$ 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Solution { public boolean findNumberIn2DArray (int [][] matrix, int target) { if (matrix == null || matrix.length == 0 || matrix[0 ].length == 0 ) return false ; int m = matrix.length, n = matrix[0 ].length; for (int i = 0 ; i < m; i++) { for (int j = 0 ; j < n; j++) { if (matrix[i][j] == target) { return true ; } } } return false ; } }
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户 内存消耗:44 MB, 在所有 Java 提交中击败了85.50%的用户
解法二 线性查找,在解法一中,暴力查找明显没有充分利用数据的特征,数组元素本身在一定程度上是有序的,我们利用这种有序性可以有效降低查找的次数。不难发现以数组右上角的值作为起始值与target
进行比较,如果值比target
大,继续往下查找,如果值比target
小,继续往左查找,如果超过了数组的边界,或者查找的位置到达了左下角也没能找到target
则返回false
,如果找到了则返回true
。查找过程中,往左最多查找n
次,往下最多查找m
次,总的查找次数不超过m + n
次。
时间复杂度:$O(m + n)$ 空间复杂度:$O(1)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution { public boolean findNumberIn2DArray (int [][] matrix, int target) { if (matrix == null || matrix.length == 0 ) return false ; int m = matrix.length, n = matrix[0 ].length; int x = 0 , y = n - 1 ; while (x < m && y >= 0 ) { if (matrix[x][y] == target) { return true ; } else if (matrix[x][y] < target) { x++; } else { y--; } } return false ; } }
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户 内存消耗:43.9 MB, 在所有 Java 提交中击败了92.41%的用户
-------------本文结束 感谢您的阅读-------------
文章对您有帮助,可以打赏一杯咖啡,鼓励我继续创作!