Num4-二维数组中的查找
一、题目描述
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
二、分析题目
1. 二维数组 每行 左 -> 右 递增
2. 二维数组 每列 上 -> 下 递增
3. 即数组中 无重复 元素
4. 判断二维数组 有无待查找 元素
在上图的二维数组中,判断元素7是否存在,返回true
三、方法
1.利用数组列递增特性(不是最好的方法)
经过观察,可知,若待查找元素 m
m < matrix[row][col]
那么 m 就不需要再继续和之后的列进行比较了(因为m必定小于后续列的值)
举个栗子,一上面的二维数组为matrix,待查找元素为 7 .
7 < matrix[0][2] // matrix[0][2] = 8
因此 7 就不必在和 8 之后的 9 进行比较,也就是不必和 matrix[ 0 ][ 3 ] 比较, 也就是7在下图这一部分
所以总结以下规律
- 若 m < matrix[ row ][ col ], 则 m 不需要再与后续行列元素进行比较,换句话说,待查找元素,在 matrix[ row ][ col ] 的左部分
代码如下:
//面试题4 查找二维数组中的值
public static boolean search(int[][] matrix, int k){
int rows = matrix.length;
int cols = matrix[0].length;
for(int row = 0; row < rows; row++){
for (int col = 0; col < cols; col++){
if(matrix[row][col] == k)
return true;
if(matrix[row][col] > k)
cols = col; // 将边界设置为当前的column
}
}
return false;
}
2. 效率更高的方法(书上的方法)
第一种方法的缺点: 一开始想出的方法,(也就是上面的方法),只用到了列递增的特点。但是并没有用到行递增的特点。因为(还是按照上面的例子)若要找7。再与8(matrix[ 0 ][ 2 ] )比较之后不能直接抛弃1、2、3行
书中的方法:
试着从数组的右上角开始进行比较,这样子就可以同时利用行递增,与列递增。还是一查找7为例。
- 左上角元素为 9 ,9 > 7, 那么 9 这一列(12,13,15)都大于7,可以抛弃(向左移动一列)
- 新的左上角元素为 8 ,同 9一样, 可以抛弃(向前移动一列)
- 新的左上角元素为 2,2 < 7, 那么在2之前的元素(1)都肯定比7小,可以抛弃,向下移动一行
- 最终就会到左下角的元素
简单来说,就是通过从右上角进行比较,若待查元素大于数组中的值那么就往下移动一行;若小于数组中的值,则向左移动一列



public static boolean Best(int[][] matrix, int k){
int rows = matrix.length;
int cols = matrix[0].length;
//从右上角开始比较
int current_row = 0; //当前行
int curretn_col = cols - 1; //当前列
while(current_row<rows && curretn_col>=0){
if(matrix[current_row][curretn_col] == k)
return true;
if(matrix[current_row][curretn_col] > k)
curretn_col--;
if(matrix[current_row][curretn_col] < k)
current_row++;
}
return false;
}
主函数
public static void main(String[] args) {
int[][] matrix = {{1,2,8,9},
{2,4,9,12},
{4,7,10,13},
{6,8,11,15}};
for (int[] rows : matrix){
for (int data : rows)
System.out.print(data + " ");
System.out.println();
}
boolean flag = search(matrix,5);
// boolean flag = Best(matrix, 7);
if (flag) {
System.out.println("包含");
} else System.out.println("不包含");
总结
自己想到的方法只是使用了列递增的特点,并不能同时使用行列递增特点,书中的方法从右上角开始查找,就可以将行列递增都应用到,并且时间复杂度也是最优。
今后还是得多观察,将已有的条件都用起来
这次插的图太粗糙了~