【力扣-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)
相关推荐
金銀銅鐵6 小时前
[Python] 基于欧几里得算法,实现分数约分计算器
python·数学
Lyn_Li8 小时前
Kaggle Top 5 | 198只股票、200条数据的金融预测——BattleFin高分方案从零复现
python·kaggle·比赛复盘·金融预测
先吃饱再说11 小时前
判断回文字符串,从一行代码到双指针优化
算法
小九九的爸爸13 小时前
前端想要入门Agent开发,要具备哪些Python基础?
python·agent·ai编程
黄敬峰13 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
阿耶同学14 小时前
手把手教你用 LangGraph 搭建三层嵌套 Agent 架构
python·程序员
得物技术15 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六18 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术19 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试