「剑指Offer 04.二维数组中的查找」

本文介绍了如何在一个按行和列递增排序的二维数组中查找目标整数。通过从左下角开始遍历,利用行和列的有序性进行排除,实现了O(N+M)的时间复杂度和O(1)的空间复杂度的查找算法。具体策略是:如果当前元素大于目标则减小行索引,小于目标则增加列索引,等于目标则返回找到。
摘要由CSDN通过智能技术生成
「剑指Offer 04.二维数组中的查找」
题目描述(level 中等)

在一个 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
思路分析

结合题意,二维数组matrix[n][m]每一行都是递增的,每一列都是递增的,可以得出在矩阵中数字最小值在左上角;而最大值在右下角。分别使用i,j表示行、列坐标。其中i的取值范围为[0,n)j的取值范围为[0, m)。那么如何某一列或者某一行呢?将矩阵展开如下

[[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]]

第一行[1, 4, 7, 11, 15]就可以表示为:matrix[0][j] 0 <= j < m。而与之对应的第一列则可以表示为:matrix[i][0] 0 <= i < n。单独看某一行,如果matrix[i][j] > target则可以排除下方的一整行,即i--。同样的如果matrix[i][j] < target则可以一列,逐渐往右侧逼近,j++

1471115
2581219
3691622
1013141724
1821232630

假设target = 9,按照整行整列的消除(从左下角开始遍历),即从“18”开始遍历整个矩阵,现在明确的是18>9而在18所在的行中,其为最小值,所以可以直接跳过这一行,即i--,同理倒数第二行也可以消除。当遍历到第三行时,需要知道的是,下面两行已经被排除了,不会在以后的遍历过程中走到,其实此时的表格已经是三行五列了。而从左往右是递增的,从上往下也是递增的,可以得出结论3是其所在列中的最大值(下面两行已经被排除),3<9一定可以得出此列没有比9还大的数字,故直接排除,执行j++在下一列中寻找。思路总结如下:

  • 从左下脚开始遍历 i,j。
  • 从左往右看:数字大小逐渐递增,单独一行看左侧的数字是最小的,遍历时如果有 matrix[i][j] > target,则可以排除一行,也即 i–;
  • matrix[i][j] < target 则可以消除一整列,即j++,
  • matrix[i][j] == target 返回true
代码实现
class Solution {
  public static boolean findNumberIn2DArray(int[][] matrix, int target) {
    if (null == matrix || matrix.length < 1) {
      return false;
    }
    int i = matrix.length - 1, j = 0;
    while (i >= 0 && j < matrix[0].length) {
      if (matrix[i][j] > target) {
        i--;
      } else if (matrix[i][j] < target) {
        j++;
      } else {
        return true;
      }
    }
    return false;
  }
}
复杂度

时间复杂度O(N+M):即使循环遍历整个矩阵,时间复杂度为N+M,扫描到每一个数字。

空间复杂度O(1):未使用额外的内存空间。

链接

二维数组中的查找

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快乐二狗呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值