剑指offer04:二维数组的查找
在一个 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。
package leetcode;
public class Salvation {
public boolean findNumberIn2DArray(int[][] matrix,int target) {
boolean res = false;
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
res = false;
}else {
int n = matrix.length;
int m = matrix[0].length;
int a = 0;
A:for (int i = a; i < m; i++) {
B:for (int j = 0; j < n; j++) {
if (matrix[j][i]==target) {
res = true;
break A;
}else if (matrix[j][i]>target) {
break B;
}
}
if (matrix[0][i]==target) {
res = true;
break A;
}else if (matrix[0][i]>target) {
a = i-1;
}
}
}
return res;
//1.暴力法:
// boolean re = false;
// if (matrix==null||matrix.length==0||matrix[0].length==0) {
// re = false;
// }else {
// int n = matrix.length;
// int m = matrix[0].length;
// for (int i = 0; i < n; i++) {
// for (int j = 0; j < m; j++) {
// if (matrix[i][j]==target) {
// re = true;
// break;
// }
// }
// }
// }
// return re;
//2.线性解题法:
// boolean re = false;
// if (matrix==null||matrix.length==0||matrix[0].length==0) {
// re =false;
// }else {
// int n = 0;
// int m = matrix[0].length-1;
// while (n<matrix.length&&m>-1) {
// if (matrix[n][m]==target) {
// re = true;
// break;
// }else if (matrix[n][m]>target) {
// m--;
// }else if (matrix[n][m]<target) {
// n++;
// }
// }
// }
// return re;
}
}
总结:总共写了三种方法,
第一种:自己想的希望减少时间和空间的方法,从左上角开始遍历元素,每次向下遍历,遇到大于目标值的返回,然后向右遍历,遇到大于目标数的返回,然后定位到横向大于目标数的前一个数。依次寻找。但每次都要经历两重for循环,时间,空间消耗反而更大。
第二种:暴力解法,直接遍历数组。
第三种:线性解法,从数组右上角的元素开始读取,往左依次减小,往下依次增大,所以,若元素值大于目标数,向左走一位,若元素小于目标数,则向下走一位。