剑指 offer 学习记录-二维数组的查找

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("不包含");

总结

自己想到的方法只是使用了列递增的特点,并不能同时使用行列递增特点,书中的方法从右上角开始查找,就可以将行列递增都应用到,并且时间复杂度也是最优。
今后还是得多观察,将已有的条件都用起来

这次插的图太粗糙了~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值