【剑指offer】 二维数组的查找

一、题目

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

二、思路

首先,思考为空的条件例如arr =  [[ ]] 的情况,要小心假如只是单纯判断arr的长度是否为0,是不正确的,因为内层的空列表会算长度是1,所以要遍历arr并看它遍历出来的元素的长度是不是0,假如是直接return False,因为空的二维数组是找不到目标的,与此同时,假如测出长度不是0的时候就要break,否则像下面的3行3列数组,它判断了第一次不是0的时候还会判断第二第三次。然后才是在脑海里面构造出数组的形状,例如:

[
    [1, 4, 8], 
    [2, 6, 11], 
    [3, 7, 12]
]

假设查找目标是7(target = 7),选的应该是第一行的最后一个元素作为开始元素,这个点因为当target比它(arr[0][2])要小时,只有左边的数才可能比arr[0][2]要小所以target就会落在左边的区域,淘汰了arr[x][2]这一列,因为每一列都按照从上到下递增的。target将不会落在灰色区域。所以指针应该往左走。

选这个点的原因是它的左边都比他小,下边都比它大,而且位于边界,举例“4”,虽然它也是左边都比他小,下边都比它大,但是有“8”在右边,当你判断的时候条件就不能唯一了,不知道应该是向左走还是向右走。

得到下一个元素arr[0][1]这个元素比target小,则同理,target不可能落在左边区域,以为左边的数比arr[0][1]还要小,所以要向下走。最后得到目标7。

三、代码实现

class Solution:
    # array 二维列表
    def Find(self, target, array):
        # write code here
        i, j = 0, len(array) - 1
        for arr in array:
            if len(arr) == 0:
                return False
            else:
                break
        while i <= len(array) - 1 and j >= 0:
            if array[i][j] == target:
                return True
            elif array[i][j] > target:
                j -= 1
            elif array[i][j] < target:
                i += 1
        return False

四、测试

测试一:

target存在于数组中:

if __name__ == '__main__':
    A = [[1, 4, 8], [2, 6, 11], [3, 7, 12]]
    so = Solution()
    if so.Find(6, A):
        print('find it')
    else:
        print('not find')

测试结果

find it
Process finished with exit code 0

测试二:

target不存在于数组中:

if __name__ == '__main__':
    A = [[1, 4, 8], [2, 6, 11], [3, 7, 12]]
    so = Solution()
    if so.Find(16, A):
        print('find it')
    else:
        print('not find')

测试结果:

not find
Process finished with exit code 0

测试三:

空二维数组

if __name__ == '__main__':
    A = [[1, 4, 8], [2, 6, 11], [3, 7, 12]]
    so = Solution()
    if so.Find(6, [[]]):
        print('find it')
    else:
        print('not find')

测试结果

not find
Process finished with exit code 0

牛客网测数据:

运行时间:222ms

占用内存:5752k

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值