zoukankan      html  css  js  c++  java
  • 剑指Offer_#4_二维数组中的查找

    剑指Offer_#4_二维数组中的查找

    Contents

    题目

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

    [
      [1,   4,  7, 11, 15],
      [2,   5,  8, 12, 19],
      [3,   6,  9, 16, 22],
      [10, 13, 14, 17, 24],
      [18, 21, 23, 26, 30]
    ]

    给定 target = 5,返回 true。
    给定 target = 20,返回 false。

    限制:
    0 <= n <= 1000
    0 <= m <= 1000

    思路分析

    方法1:暴力搜索

    两轮循环,暴力搜索,可以通过,但是因为没有利用到题目给出的条件“每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序”,所以肯定不是最优解。

    方法2:从右上角(左下角)开始查找

    最自然的想法肯定是从左上角开始遍历矩阵,但是如果从左上角开始遍历,是没法利用到题目条件来优化算法的,因为从左上到右下,无论向下走还是向右走,数字都是增大,无法进行决策。
    但是如果从右上角开始向左下角查找,我们发现,向左走数字减小,向下走数字增大。那么其实就是类似于在二叉搜索树查找一个数字

    • 如果当前数字小于target,则向下移动,排除当前行
    • 如果当前数字大于target,则向左移动,排除当前列

    这样就可以不用遍历所有的数字。因为每次移动的时候,就相当于排除掉一行或者一列,时间复杂度变成O(m+n)。
    同理,从左下角开始查找也是类似的,不再赘述。

    解答

    解答1:暴力搜索

    class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
                return false;
            for(int i = 0;i < matrix.length;i++){
                for(int j = 0;j < matrix[i].length;j++){
                    if(matrix[i][j] == target) return true;
                }
            }
            return false;
        }
    }

    复杂度分析

    时间复杂度:O(n2)
    空间复杂度:O(1)

    关于数组和null

    1. 数组不属于java的基本类型,属于对象。
    2. 基本类型只有 boolean, byte, short, char, int, long, float, double 8种。
    3. null只可以赋值给对象的引用变量,不可以赋值给基本类型变量。

    所以本题中考虑的特殊情况,不仅仅要考虑数组长度为0的情况,还要考虑输入为null值的情况。

    解答2:从右上角开始查找

    class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
                return false;
            int rows = matrix.length;
            int cols = matrix[0].length;
            //从右上角元素开始查找
            int row = 0;
            int col = cols - 1;
            //循环条件是不超出matrix坐标范围
            while(row <= rows - 1 && col >= 0){
                if(matrix[row][col] == target) return true;
                //ERROR:下面两句不可以写成if,否则col--之后可能已经越界了,到最后一个判断语句就会出现越界
                else if(matrix[row][col] > target) col--;
                else if(matrix[row][col] < target) row++;
            }
            //循环结束了还没有找到target,就返回false
            return false;
        }
    }

    复杂度分析

    时间复杂度:O(m+n)
    空间复杂度:O(1)

  • 相关阅读:
    jQuery
    MySQL的引入,绿色包下载和应用
    jsp引用JSTL核心标签库
    Servlet的引入
    Servlet访问Javabean并传结果给jsp
    Spring MVC 中获取session的几种方法
    面试必问系列——hashmap的默认扩容阈值是大于12还是大于等于12
    面试必问系列——重写equals为什么一定要重写hashcode
    分析spring4和spring5日志中的不同
    mysql 查询参数尾部有空格时被忽略
  • 原文地址:https://www.cnblogs.com/Howfars/p/13405855.html
Copyright © 2011-2022 走看看