一天一算法 day1--二维数组中查找

版权声明:本博客所有文章由leoss原创,转载请注明出处 https://blog.csdn.net/qq_14869093/article/details/85647254

致2019

2018年就这样匆匆过去,这一年过得太单调,太平凡,每天上班下班,日复一日。偶尔学些所谓的新技术,良心发现不能懒惰就会啃几天书。虽然自己平时也会零零散散的写一些技术日志,记录下开发过程中遇到的困难,但都是随手记录的方式,写完就躺在笔记软件里了,也没有很好的整理,它们重见天日的机会渺茫,因为都在脑子里了啊,哈哈。从大学到现在几年之中,已经尝试过好几次搭建自己的博客,不过搭完也就完了,有自己搭vps,gitbub,博客园等等,甚至CSDN的博客也是从2015年就已经注册了的,但是没有一个坚持下来。这段时间在看《剑指offer》,里面的题目和解题思路都非常不错,但是原书基于C/C++实现的。我只能自己用java写一遍,写得对不对,好不好也没人知道,写完也没有整理记录。于是萌生了一个将java的实现通过博客来公布,一是供朋友们参考学习;二是希望有人交流沟通,能发现些什么问题。三是监督自己坚持写博客,作为2019的一个小目标吧。

好了下面进入今天的主题。

本题代码已上传到:gitbub

题目

面试题3:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
图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

猜你喜欢

转载自blog.csdn.net/qq_14869093/article/details/85647254