【力扣-Python-74】搜索二维矩阵(middle)

74. 搜索二维矩阵

题目

给定一个m×n的整数矩阵,它有两个特殊性质:(1)每一行都是从小到大排序的;(2)每一行的第一个元素都大于上一行的最后一个元素。现在给你一个目标值,要判断这个值是否存在于矩阵中。要求时间复杂度为O(log(m×n))

思路及代码

**思路1:**逐行二分

因为每一行都是有序的,所以可以逐行二分

python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        # 逐行进行二分查找
        for row in matrix:
            left, right = 0, len(row) - 1
            while left <= right:
                mid = (left + right) // 2
                if row[mid] == target:
                    return True
                elif row[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
        return False
  • 时间复杂度为 m*log(n)
  • 这种解法没有利用第二个性质,即行与行之间也是有序的,整个矩阵其实是全局有序

思路2:行级+行内二分

先用二分查找确定目标值在哪一行,然后再在那一行内部进行二分查找

python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m, n = len(matrix), len(matrix[0])
        # 首先二分查找定位目标行
        top, bottom = 0, m-1
        while top <= bottom:
            mid = (top + bottom) // 2
            # 如果目标值在这一行的范围内
            if matrix[mid][0] <= target <= matrix[mid][n-1]:
                break
            elif matrix[mid][0] > target:
                bottom = mid - 1
            else:
                top = mid + 1
        # 没有找到合适的行
        if top > bottom:
            return False
        # 目标值在行mid中
        row = mid
        # 开始在目标行内进行二分查找
        left, right = 0, n-1
        while left <= right:
            mid = (left + right) // 2
            if matrix[row][mid] == target:
                return True
            elif matrix[row][mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return False
  • 时间复杂度为 O(log(m) + log(n)),等价于 O(log(m×n)),符合题目要求

思路3:整体二分

因为整个矩阵行内有序,行间也有序,可以把这个二维矩阵想象成一个一维的有序数组

  • 定义一个映射关系,对于一维索引,用整除列数得到行号,用取余列数得到列号
  • 即:一维索引 index ---> 二维行号 = index // n,二维列号 = index % n
  • 有了这个映射,就可以直接对整个矩阵进行一次二分查找
python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m, n = len(matrix), len(matrix[0])
        left, right = 0, m * n - 1
        while left <= right:
            mid = (left + right) // 2
            # 一维索引映射为二维索引的行和列
            row = mid // n
            col = mid % n
            if matrix[row][col] == target:
                return True
            elif matrix[row][col] < target:
                left = mid + 1
            else:
                right = mid - 1
        return False
  • 时间复杂度为 O(log(m×n))
  • 空间复杂度是常数级别 O(1)
相关推荐
怪侠_岭南一只猿2 小时前
爬虫工程师学习路径 · 阶段五:数据存储与清洗(完整学习文档)
爬虫·python·学习
圣保罗的大教堂2 小时前
leetcode 1878. 矩阵中最大的三个菱形和 中等
leetcode
咱就是说不配啊2 小时前
3.16打卡day30
数据结构·c++·算法
MicroTech20252 小时前
MLGO微算法科技面向复杂非局域模型的量子虚时演化新方案:一种无需局域性假设的量子虚时演化新算法
科技·算法·量子计算
weixin_649555672 小时前
C语言程序设计第四版(何钦铭、颜晖)第八章指针之判断回文字符串
c语言·开发语言·算法
luckycoding2 小时前
3392. 统计符合条件长度为 3 的子数组数目
数据结构·算法·leetcode
飞Link2 小时前
深度解析多维时序数据异常检测:原理、挑战与架构之道
python·数据挖掘·回归
TracyCoder1232 小时前
LeetCode Hot100(69/100)—— 139. 单词拆分
算法·leetcode·职场和发展
l1t2 小时前
利用omnicoder-9b模型编写把扫描版pdf转成文字版pdf的程序
人工智能·python·pdf