240. 搜索二维矩阵 II(Search a 2D Matrix II)

难度:中等 | 主题:二分查找、矩阵、双指针

题目

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:每行的元素从左到右升序排列;每列的元素从上到下升序排列。

示例

 
输入: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
 

思路

先讲个故事:在十字路口找路

你站在一个十字路口,北边的路越走越热(数字变大),东边的路越走越冷(数字变小)。你要找一个温度 15°C 的地方。

你站在右上角——这里是你北边最热、东边最冷的地方。如果当前位置比 15 热,说明这条路往北只会更热,你往东走;如果比 15 冷,说明这条路往东只会更冷,你往北走。每一步都排除一行或一列。


引导式推导:Z 字形搜索

右上角开始搜索。右上角是当前行的最大、当前列的最小。


graph TD

    A["从右上角开始<br/>(0, n-1)"] --> B{"当前值 vs target"}

    B -->|当前值 > target| C["当前列都太大<br/>列左移 col--"]

    B -->|当前值 < target| D["当前行都太小<br/>行下移 row++"]

    B -->|相等| E["找到! return True"]

    C --> F{"越界?"}

    D --> F

    F -->|否| B

    F -->|是| G["return False"]

每次比较都能排除一行或一列,最多走 m+n 步。

解法时间空间
右上角双指针(推荐)O(m+n)O(1)
逐行二分O(m log n)O(1)

代码

 
def searchMatrix(self, matrix, target):
 
    if not matrix or not matrix[0]:
 
        return False
 
    m, n = len(matrix), len(matrix[0])
 
    row, col = 0, n - 1
 
    while row < m and col >= 0:
 
        current = matrix[row][col]
 
        if current == target:
 
            return True
 
        elif current > target:
 
            col -= 1
 
        else:
 
            row += 1
 
    return False
 

复杂度

指标解释
时间O(m+n)每次排除一行或一列
空间O(1)只用两个指针

实战考量

频率分析

出现在:矩阵搜索经典题。考察对二维有序结构的搜索策略,不能只会一维二分。字节/美团常考。

延伸思考

Q:为什么从左下角开始也可以?

A:左下角是当前列最大、当前行最小,同理可推。

Q:如果矩阵极大(10^5 x 10^5),m+n 和 m*log(n) 哪个好?

A:10^5 + 10^5 = 210^5,10^5 * log(10^5) ≈ 1.710

Q:如果要求统计出现次数呢?

A:找到后向左右扩展,或用二分找上下界。

易错点

  • 起始位置必须是右上角或左下角

  • 循环条件是 row < m and col >= 0

  • 从左上角开始不行:右和下都变大,无法确定方向


生活类比

Z 字形搜索 → 在十字路口找路

你站在一个路口,北边越走越热,东边越走越冷。你要找某个温度——每一步都能排除一条路。方向感就是你的二分法:热了往东,冷了往北,迟早走到。


相关题目

题目关系
74搜索二维矩阵矩阵可拉平成一维有序
378有序矩阵中第K小的元素有序矩阵第 K 小

→ 返回题单:LeetCode学习路线图 > 八、二分查找

速记卡(面试闪卡)

Q1:一句话讲清「240. 搜索二维矩阵 II(Search a 2D Matrix II)」到底是什么?

A:从右上角出发,每次比较排除一行或一列,Z 字形走到 target,时间 O(m+n)。

Q2:十字路口找温度(Z-shape search) —— 怎么理解?

A:类比:站在右上角——北边最热、东边最冷。当前比目标热就往东走(排除整列),比目标冷就往北走(排除整行)。每一步排除一行或一列,像顺着温度梯度抄了近路。(Eliminate a row/col)

Q3:双指针游走(two pointers) —— 怎么理解?

A:类比:row=0、col=n-1 起步,current==target 返回;>target 则 col—;<target 则 row++;越界 return False。只两个指针,空间 O(1)。别从左上角开始——右和下都变大,方向就懵了。(Start at corner)

Q4:复杂度与起点选择(O(m+n) time) —— 怎么理解?

A:类比:每次砍掉一行或一列,最多走 m+n 步,时间 O(m+n)、空间 O(1)。左下角同理可走。超大矩阵时双指针远胜逐行二分 O(m log n)——2×10⁵ 吊打 1.7×10⁶。(Beats binary search)

Q5:扩展与易错(binary search vs two pointers) —— 怎么理解?

A:类比:起点必须右上或左下;循环条件 row=0。若统计出现次数可找到后向两侧扩展。面试官常拿它对比一维二分,考你对二维有序结构的嗅觉。(2D ordered sense)

Q6:核心速记主线有哪些?

  • 题目:每行每列升序的矩阵中搜 target

  • 思路:右上角出发 Z 字形排除行列(two pointers)

  • 代码:大则左移列、小则下移行

  • 复杂度:时间 O(m+n)、空间 O(1)

  • 实战:起点须右上/左下,勿从左上开始

口诀

A:矩阵有序行列排,

右上起步莫发呆;

大则左移小下移,

排除行列自然来。

相关链接