算法学习 day1--二维数组中查找


本题代码已上传到:gitbub

题目

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

题目分析

这题相对简单,就是一个矩阵搜索问题。就是从一个角开始搜索(右上/左下)。因为矩阵是有序的,在右上/左下的数字,必定是这行或这列的极值(最大或最小值),只要通过一次比较,那必定能排除一行或一列,通过不断循环,很快就能找到结果。

图2的流程很形象的解释了解题逻辑,比如搜索整数7,本题是递增序列,那么如果我们从右上角开始,右上角的9,是9所在行的最大值,是9所在列的最小值,只要和给定的数字7比较大小,就知道可以去掉一行或一列了,这里是去掉9所在的第四列。然后进入下次循环,一直比较直到找到数字返回true,或者矩阵为空返回false。

图2:图2

那么为什么不从中间开始呢,看看下边图3就大致理解了,这个书中的解法里其实有个降维的思想。如果从矩阵中间开始搜索,除边角外任何一个位置都会有4个方向,虽然通过比较,能去掉一个角(图中白色),表面看起来是去掉了2个方向,但是移动比较位置后又会有4个方向(或3个),无穷无尽,也许最后能找到结果,但是程序的逻辑会变得非常复杂(几个方向意味着几次比较和几个可能),而本题的解法,直接从4个方向降为2个方向,直接简化了判断逻辑,且缩小后的矩阵依然符合程序的判断逻辑。

图3:图3

代码实现
 private static boolean checkMatrix(int[][] matrix, int num) {
        boolean exist = false;
        if (matrix != null && matrix.length > 0 && matrix[0].length > 0) {
            // TODO 这里省略对每行长度的检查,只是简单从第1行判断是否为空,如果考虑健壮性,是需要检查的,不在本题的考察范围
            int row = matrix.length;
            int col = matrix[0].length;
            for (int i = 0, j = col - 1; i < row && j >= 0; ) {
                if (matrix[i][j] == num) {
                    exist = true;
                    break;
                } else if (matrix[i][j] > num) {
                    j--;
                } else {
                    i++;
                }
            }
        } else {
            System.out.println("matrix is empty");
        }
        return exist;
    }
测试用例
public static void main(String[] args) {
        int[][] matrix = {
                {1, 2, 8, 9, 11},
                {2, 4, 9, 12, 13},
                {4, 7, 10, 13, 16},
                {6, 8, 11, 15, 21}};

        int num1 = 1;
        System.out.println(num1 + " in matrix is " + checkMatrix(matrix, num1));
        int num2 = 21;
        System.out.println(num2 + " in matrix is " + checkMatrix(matrix, num2));
        int num3 = 16;
        System.out.println(num3 + " in matrix is " + checkMatrix(matrix, num3));
        int num4 = 0;
        System.out.println(num4 + " in matrix is " + checkMatrix(matrix, num4));
        int num5 = 30;
        System.out.println(num5 + " in matrix is " + checkMatrix(matrix, num5));
        int num6 = 3;
        System.out.println(num6 + " in matrix is " + checkMatrix(matrix, num6));

        int num = 4;
        matrix = null;
        System.out.println(num + " in matrix is " + checkMatrix(matrix, num));

    }
测试结果

1 in matrix is true
21 in matrix is true
16 in matrix is true
0 in matrix is false
30 in matrix is false
3 in matrix is false
matrix is empty
4 in matrix is false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值