每日一道剑指offer-二维数组中的查找

题目:

在一个 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,矩阵的每一列按照从上到下递增的顺序排序。根据这两个先决条件和题目要求,有几种方法解决。

第一种方法:双重for循环,遍历矩阵中的每个数,判断每个数是否和目标数相等。(时间复杂度高)

def findNumberIn2DArray(matrix,target):
    for array in matrix:
        for num in array:
            if num == target:
                return True
    else:
        return False

 

第二种方法:在第一种双重for的基础上,进行改进,利用python特性,改为单for循环。(遍历矩阵,得到一维数组,只需要判断目标数是不是在每个数组中即可.)

def findNumberIn2DArray2(matrix,target):
    for array in matrix:
        if target in array:
            return True
    else:
        return False

 

第三种方法:用到了题目中的两个特性上下左右都是递增的(从小到大的)。这样我们可以定义两个指针:行列指针,

                     1,从矩阵的最右上角进行比较,当目标数大于当前元素时,那么将列指针向下移动(因为当前元素下边的数都比当前元素大);

                     2,当目标数小于当前元素时,行指针向左移动(因为当前左边的数都比当前元素的小);

                     3,当目标数等于当前元素时,返回True;最终循环完后没找到,则返回False;

def findNumberIn2DArray3(matrix,target):
    if not matrix: #若数组为空,返回 false
        return False
    row =0
    column = len(matrix[0])-1 #初始化行下标为 0,列下标为二维数组的列数减 1

    while row<=(len(matrix)-1) and column>=0:
        if matrix[row][column] >target: #如果 num 大于 target,列下标减 1
            column-=1
        elif matrix[row][column] <target: #如果 num 小于 target,行下标加 1
            row+=1
        else: #如果 num 和 target 相等,返回 true
            return True
    return False

总结下来:

       这种方法也就是按照这两条思路来:

                    1,如果当前元素大于目标值,说明当前元素的下边的所有元素都一定大于目标值,因此往下查找不可能找到目标值,往左查找可能找到目标值

                    2,如果当前元素小于目标值,说明当前元素的左边的所有元素都一定小于目标值,因此往左查找不可能找到目标值,往下查找可能找到目标值

      根据这两条代码就很容易写出来了。这个是最推荐的方法,根据题目的先决条件,来进行思考。

执行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值