【力扣-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)
相关推荐
信奥卷王8 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵8 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
全栈练习生9 小时前
AI Agent 沙箱
python·ai
徐小黑ACG10 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
码完就睡10 小时前
数据结构——红黑树
数据结构
码爸10 小时前
数据结构详细介绍
数据结构
Navigator_Z10 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
SEO_juper10 小时前
用 Python 写一个 GEO 可见性检查脚本:你的网站现在能被 AI 引用吗
开发语言·人工智能·爬虫·python·seo·外贸独立站
数智工坊10 小时前
视觉SLAM第12讲|地图构建:单目稠密重建、RGB-D点云与八叉树地图全解析
人工智能·深度学习·矩阵·机器人