剑指offer 之 二维数组的查找

题目:

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

思路:

从数组的右上角或左下角开始搜索,大于当前值,向下(右)移动;小于当前值向左(上)移动。

为什么要从右上角或左下角开始搜索呢?我们通常习惯于从左上角也就是数组的第一个元素开始搜索,也不排除部分人比较特别喜欢从最后一个元素开始找,但是这种方法可行吗?我们来看一个例子:

\left [ \begin{matrix} 1& 2& 3& 4& 5\\ 6& 7& 8& 9& 10\\ 11& 12& 13& 14& 15\\ 16& 17& 18& 19& 20 \end{matrix} \right ]

现在我们想从上面的二维数组中找到13,考虑两种情况:

1. 如果从左上角开始搜索,1<13(ps: 右方元素大于当前元素,下方元素也大于当前元素,该往哪里走呢?),我们无法确定该往哪个方向走,当然也可以两个方向都尝试一下,这样查找的复杂度会以2^n递增,且有很多重复计算,不是最佳选择。

2. 现在考虑从右上角出发,5<13(ps:左边元素都小于当前元素,下方元素都大于当前元素,那我们当然往下走了),10<13,继续向下走,15>13,向左走,14>13,继续向左走,找到13啦!路径:5 -> 10 ->15 -> 14 ->13

这就知道我们为什么要选择右上角和左下角了,因为它的下一个选择具有唯一性!那我们再怎么确定数组里没有这个元素呢?当我们的指针坐标超过边界依然没有找到我们的目标,那就说明目标没有隐藏在数组中。

代码:

'''
题目:
    在一个二维数组中(每个一维数组的长度相同),
    每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
    请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
    从右上角(左下角)开始搜索,大于当前值,向下(右)移动;小于当前值向左(上)移动。
    代码是从右上角开始搜索
'''
class Solution:
    def Find(self, array, num):
        i, j = 0, len(array[0])-1
        while i < len(array) and j >= 0:
            print(array[i][j], end=' ')    # 打印中间路径
            if array[i][j] == num:
                return True
            elif array[i][j] > num:
                j -= 1
            else:
                i += 1
        return False

if __name__ == '__main__':
    matrix1 = [
        [1,2,3,4,5],
        [6,7,8,9,10],
        [11,12,13,14,15],
        [16,17,18,19,20]
    ]
    solution = Solution()
    print("Find 1:")
    assert(solution.Find(matrix1, 1))   # ()里的表达式为True正常执行,否则Error
    print("\nFind -1:")
    assert(not solution.Find(matrix1, -1))
    print("\nFind 16:")
    assert(solution.Find(matrix1, 16))
    print("\nFind 21:")
    assert(not solution.Find(matrix1, 21))
    print("\nok!")

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值