剑指offer第一题 [二位数组的查找]

二维数组的查找
时间限制:1秒  空间限制:32768K  热度指数:622393
本题知识点:  查找

题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。


解题思路:

        一般对于编程题来说,看懂题是解题的关键,我们先分析题目,题目可以简单概括为一句:

            “排序好的二维数组,输入整数判断整数是否在该二维数组中”

        读好题目之后不要着急上去就写代码,我们应该滤清思路,为了方便找到解题的思路,先画一个如题所述的二维数组


画出来之后,肯定会有一种思路,只要我们遍历这个二维数组就可以了呀,这不是很简单的问题吗?

那么好,我们的第一种解题思路就诞生了,遍历二维数组每一次都比对,只要相等就返回true,不等就返回flase


public boolean FindNumber(int number , int [][] array){
        boolean result = false;
        if(array.length == 0){
            return result;
        }
        //数组的行数
        int rowLength = array.length;
        //数组的列数
        int colLength = array[0].length;
        for (int i = 0; i < rowLength; i++) {
            for (int j = 0; j < colLength; j++) {
                if(array[i][j] == number){
                    result = true;
                }
            }
        }

        return result;
    }

ac

但是要是这个二位数组是1000X1000或者更大,这个时候我们的思路就会超时,因为进行了很多不必要的对比

那么有没有更好的办法,去掉那些不必要的对比呢?

上面的算法,我们还没利用到已经排序的这一特性,我们只要按照这个特性就可以写出更高效的算法了,我们拿30为例,因为是排序好的,我们只要把这个问题分解成每一行的最值对比30就可以找出了

所以上一行的数都要比下一行小,我们先找每一行最大的(也就是每一行最右边的),去跟30对比,那么就会出现2种情况,要么比30大,要么比30小

1.如果比30小,说明30肯定在下面几行里,继续往下

2.如果比30大,说明30肯定在这行里,那么我们只要再次遍历这一行就可以了。(从右往左)

如图所示:


根据我们的思路优化我们的代码:

public boolean FindNumber(int number ,int [][] array){
        boolean result = false;
        if(array.length == 0){
            return result;
        }

        int i = 0;
        int j = array.length;

        while (i < array[0].length && j >= 0){
            if(array[i][j] < number){
                i++;
            }else if(array[i][j] > number){
                j--;
            }
            if(array[i][j] == number){
                result = true;
            }
        }

        return result;
    }

代码git链接


猜你喜欢

转载自blog.csdn.net/qq_40033365/article/details/79789295