【剑指 Offer II】 04. 二维数组中的查找

122 阅读2分钟

leetcode链接:剑指 Offer 04. 二维数组中的查找

题目描述

在一个 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

解题思路

方法一:双层for循环暴力查找,时间复杂度:O(n*m)空间复杂度:O(1),简单但不推荐
方法二:使用二分法查找,先找行再找列,时间复杂度:O(nlogm)空间复杂度:O(1)。
方法三:根据题目条件“从左到右递增,从上到下递增”,我们可以从左下角或右上角的元素开始进行与target对比,以左下角 matrix[n-1][0] 为例:在相同列中, matrix[n-1][0] 大于其上方的元素值,在相同行中, matrix[n-1][0] 小于其右侧的元素值,如果target大于 matrix[n-1][0] ,那么我们就从左下角右移一格成 matrix[n-1][0+1] 继续与target对比,如果target小于 matrix[n-1][0] ,那么我们就从左下角上移一格成 matrix[n-1-1][0] 继续与target对比,若找到target,则返回 true ,反之则返回 false ,右上角同理可得。时间复杂度:O(n+m)空间复杂度:O(1),为最优解,推荐使用这种方法

代码实现

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        // 矩阵若空或行数、列数为0,直接返回false
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return false;
        }
        // 读取出矩阵的行数与列数
        int rows = matrix.length;
        int columns = matrix[0].length;
        // 确定左下角的坐标
        int row = rows -1;
        int col = 0;
        while(row >=0 && col < columns){
            if(matrix[row][col] > target){
                row--; // 从左下角上移一格
            }else if(matrix[row][col] < target){
                col++; // 从左下角右移一格
            }else{
                return  true;
            }
        }
        return false;
    }
}

我的思考

想要高效地解决这道题,我们需要破除惯性思维,遇到矩阵我们不一定要从 matrix[0][0] 开始处理,我们应该结合题目条件找到其特性,根据特性研究其可行解。

通过这道题我对矩阵有了更深的理解尤其是对如下矩阵的理解:

int[][] matrixmatrix == nullmatrix.lengthmatrix[0].length
[]false0ArrayIndexOutOfBoundsException
[[]]false10
[[],[]]false20

所以在上述代码实现中,因为会出现矩阵形式为"[]"的测试用例,所以需要先判断,再读取矩阵的行数与列数,否则会报错"ArrayIndexOutOfBoundsException"

        // 矩阵若空或行数、列数为0,直接返回false
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0){
            return false;
        }
        // 读取出矩阵的行数与列数
        int rows = matrix.length;
        int columns = matrix[0].length;



此文章是我的第二篇刷题总结,比较基础,希望能和大家一起学习,我也会努力更新《剑指offer》其他题目,加油!