剑指offer面试题 - 04 二维数组中的查找

二维数组中的查找

题目描述

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

分析

以如下所示的二维数组(3x4)为例。

2  4  5  9
4  7 12 14
5 11 25 30

本题显然有暴力解法,也即顺序遍历这个二维数组,判断是否存在目标数字,对于n*m的数组,其时间复杂度为O(nm)。根据题意,这个数组的每一行、每一列都是有序的,那么我们可以考虑类似二分查找的思想。二分法每次可以排除掉潜在范围内的一半,而本题的查找为了时间效率,也是要尽可能的通过一次比较就大幅地缩小查找范围。通过题意我们知道,对于处在这样的矩阵右上角或左下角的数是具有一定特点的。对于右上角的数,处于所在行的最右,所以一定是该行最大的数;同时处于所在列的最上边,则一定是该列最小的数,左下角的数则相反。
我们以右上角的数为例,若待查找的数target大于当前右上角的数,则它比这一整行都大,可以下移一行;反之若target小于右上角数字,则它比这一整列都小,可以左移一列;然后在子矩阵中继续查找,直到找到这个数或搜索完全部行列。例如在上述矩阵中查找整数11是否存在,首先在行号0,列号3的右上角有数字9,显然11>9,则11不可能在第0行;于是下移一行,右上角变为14,11<14,不可能在第3列;左移一列,11<12;左移一列,11>7;下移一行,找到11,返回true。
C++代码如下:

bool findNumInMatrix(vector<vector<int>> & matrix, int target) {
  int rows = matrix.size();
  int cols = matrix[0].size();
  int r = 0, c = cols - 1;
  while (r < rows && c > -1) {
    if (target == matrix[r][c])
      return true;
    else if (target > matrix[r][c])
      ++r;
    else
      --c;
  }
  return false;
}

从右上角[0][cols-1]的位置开始,每次比较可以排除一行或一列,直到找到target返回true,或行列遍历完返回false。最差的情况是遍历了所有行和列,时间复杂度 O(n+m)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值