【力扣-240. 搜索二维矩阵2 ✨】Python笔记

0 阅读3分钟

🚀 从暴力解法到线性查找:LeetCode 240 题解

摘要:本文深入剖析 LeetCode 240 题「搜索二维矩阵 II」。面对行与列均有序的矩阵,我们不能简单套用二分查找,而应利用其特性从右上角开始线性查找,将时间复杂度优化至 O(m+n)O(m+n)


🔑 核心知识点:有序矩阵的特性与“Z 字形”查找

在解决这道题之前,我们需要理解二维矩阵中行有序列有序意味着什么,以及如何利用这个特性。

1. 二分查找的局限性

对于普通的有序数组,我们习惯使用二分查找。但在二维矩阵中,如果直接对每一行进行二分查找,时间复杂度是 O(mlogn)O(m \log n)

  • 问题:这虽然可行,但没有充分利用“列也是有序”这一条件。

2. 为什么从“右上角”开始?

这是本题最精妙的思路。我们选择从矩阵的右上角(或者左下角)作为起点,可以将矩阵看作一棵二叉搜索树

  • 当前元素 >> 目标值:由于该行右边的数都比当前数大,该行无解,只能向下走(寻找更大的数)。
  • 当前元素 << 目标值:由于该列下方的数都比当前数大,该列无解,只能向左走(寻找更小的数)。
  • 当前元素 == 目标值:找到答案,返回 True

这种策略每一步都能排除一行或一列,最终形成一个类似“Z”字形的搜索路径,时间复杂度仅为 O(m+n)O(m+n)


💻 题目解析:LeetCode 240. 搜索二维矩阵 II

📝 题目描述

  1. 每行的元素从左到右升序排列。
  2. 每列的元素从上到下升序排列。

📊 示例

输入:matrix = [
  [1, 4, 7, 11, 15],
  [2, 5, 8, 12, 19],
  [3, 6, 9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
], target = 5

输出:true

💻 代码实现(Python)

根据上述思路,我们从右上角开始遍历,利用指针模拟“向下”和“向左”的移动。

from typing import List

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix or not matrix[0]:
            return False
        
        # 初始化指针在右上角
        # row: 行索引,col: 列索引
        row, col = 0, len(matrix[0]) - 1
        
        # 当指针在矩阵范围内时循环
        while row < len(matrix) and col >= 0:
            if matrix[row][col] == target:
                return True
            elif matrix[row][col] > target:
                # 当前数大于目标,向左走(缩小列)
                col -= 1
            else:
                # 当前数小于目标,向下走(增大行)
                row += 1
        
        # 遍历结束未找到
        return False

📊 复杂度分析

维度分析结果说明
时间复杂度O(m+n)最坏情况下,指针需要从右上角走到左下角,遍历 m+n 个元素。
空间复杂度O(1)只使用了常数级别的额外空间(row, col 指针)。

📝 总结

这道题是经典的算法思维题。关键在于打破常规,不要试图把二维问题强行降维成一维去套用二分查找。利用矩阵的有序性,通过选取合适的起点(右上角或左下角),可以将查找过程转化为线性时间复杂度的高效操作。