剑指offer---二位数组中的查找

剑指offer—二位数组中的查找

问题分析

这一类题目的要求在给定的二维数组中判断给定的数是否存在,不存在就返回False。这些二维数组有一定的规律性,比如每一行和每一列都是递增的等等,所以在遇到二维数组或多维数组时,先看看数组是否具有一定的规律性。
下面,介绍几种比较常用的方法。
首先,最直接的方法,就是暴力求解,用这种方法最后的时间复杂度为O(MN)(M为行数,N为列数),效率是最慢的,所以这里不推荐。

其次,还有一种使用二分法来解题的,比如像下面的二维数组:在这里插入图片描述
它要求每一行从左向右递增,而且每行的第一个元素大于上一行最后一个元素。这样的二维数组可以直接“展开”一维数组,如下:
在这里插入图片描述
这样的话,就相当于在一个一维数组中判断元素是否存在了,这里用二分法求解,只不过每次得将一维的坐标转换成二维的坐标。该方法的时间复杂度为O(log(MN))。

最后,介绍一种线性时间的方法(这种方法的适用范围要比第二种方法广),也是书上提供的方法,就是根据要找的数与给定位置数的相对大小,来进一步缩小数组的范围。
在这里插入图片描述
用上面的数组作为例子,该数组的每一行从左向右递增,每一列从上到下也是递增的,和第一个例子有些不同。
假设需要寻找的数是7,而我们最先从右上角的9开始寻找。如果给定的数小于7,那么根据数组的特点,比9小的数只会出现在当前列前面的列中;同样,如果要找的数大于9,那么只会出现在当前行的下面的行中。这样一来,就缩小了数组的尺寸,在新的数组中还是从最右上角的位置开始找起。在这里插入图片描述
这一题,由于7<9,所以,下一步需要的找的点为9(第二行,第三列),由于7<9,所以仍是在左边查找,下一个位置为4:
在这里插入图片描述
而7>4,所以接下来从下面开始找:
在这里插入图片描述
这时候,正好找到的数与目标数匹配,所以返回True。如果一直没有找到,那么数组就会一直找到第0列或第M行,这是不允许的,直接返回False。
这种方法时间复杂度为O(M+N)。但是要注意,开始的点不能随便乱选,在这里我选的是最右上角,也可以选择左下角。选择右上角是因为,小于该位置的数全部在其左边,而大于此数的数全部在其下面,这个特别的地方,决定了它可以作为开始的位置,同样,左下角也可以。
但如果左上角,那么它的右边和下面的数全部大于它,所以就没有区分度,不便于缩小查找的范围,右下角也是如此。

本题的思想就是减小查找的范围,所以无论是多么复杂的结构,只要能够找到某种手段,能够将问题的范围减小,那么做起来就方便很多。

源码

class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
    # 二分法
    #     if matrix:
    #         m = len(matrix)
    #         n = len(matrix[0])
    #         print(m, n)
    #         left = 0
    #         right = m * n - 1
    #         while left <= right:
    #             print(left, right)
    #             mid = (left + right) // 2
    #             print(mid // n)
    #             if matrix[mid // n][mid % n] < target:
    #                 left = mid + 1
    #             elif matrix[mid//n][mid%n] > target:
    #                 right = mid - 1
    #             else:
    #                 return True
    #     return False

    # 根据数组的特点
        if matrix:
            m = len(matrix)
            n = len(matrix[0])
            col = 0
            row = n-1
            while col < m and row >= 0:
                if matrix[col][row] == target:
                    return True
                elif matrix[col][row] > target:
                    row -= 1
                else:
                    col += 1
        return False

由于剑指offer上面的很多题目都能在leetcode上找到原型,所以这里代码用的例子也是leetcode里的,下面是原题,大家可以使用这里的题目来练习。

leetcode第74题. 搜索二维矩阵

第240题.搜索二维矩阵 II

谢谢

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值