74. 搜索二维矩阵
从左下角或者右上角开始查找
这个方法是利用了矩阵的性质,如果我们从右上角开始遍历:
如果要搜索的 target 比当前元素大,那么让行增加;
如果要搜索的 target 比当前元素小,那么让列减小;
一、算法逻辑(逐步通顺讲解每一步思路)
该算法用于在一个满足如下性质的二维矩阵中搜索目标值 target
:
-
每行从左到右递增;
-
每列从上到下递增。
这种矩阵结构允许我们从一个特殊位置出发,以线性方式排除整行或整列。
✅ 1️⃣ 初始位置设定
我们从 右上角 开始遍历:
i = 0 # 第一行
j = n - 1 # 最后一列
这是一个非常巧妙的起点选择,因为:
-
当前元素是这一行最大值(向左变小);
-
同时又是这一列最小值(向下变大)。
✅ 2️⃣ 循环遍历矩阵
在每一步中:
-
如果
matrix[i][j] == target
,直接返回True
; -
如果
matrix[i][j] < target
,说明当前行太小,整行左边也更小,排除当前行,即i += 1
; -
如果
matrix[i][j] > target
,说明当前列太大,整列下方也更大,排除当前列,即j -= 1
。
✅ 3️⃣ 终止条件
当:
i >= m or j < 0
说明矩阵已经被完全排除,还没找到目标,返回 False
。
二、核心点总结
该算法充分利用了矩阵的有序性质,采用了极具技巧性的搜索策略:
✅ 从「右上角」出发,能够在每一步排除整行或整列,使搜索过程呈现出 单调线性收敛。
✅ 每次移动都让搜索空间减少一行或一列,效率远高于暴力遍历。
✅ 逻辑直观,不容易出错,尤其适用于不要求二分但矩阵有序性强的场景。
✅ 属于典型的「Z字形搜索」策略,也可用于拓展如:LeetCode 240、类似地形图搜索等题。
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
m, n = len(matrix), len(matrix[0])
i, j = 0, n - 1
while i < m and j >= 0: # 还有剩余元素
if matrix[i][j] == target:
return True # 找到 target
if matrix[i][j] < target:
i += 1 # 这一行剩余元素全部小于 target,排除
else:
j -= 1 # 这一列剩余元素全部大于 target,排除
return False
三、时间复杂度分析
最多向下走 m
步,向左走 n
步,总计不超过 m + n
次操作:
✅ 时间复杂度:O(m + n)
相比于二分查找的 O(log(m * n))
,在矩阵较大但稀疏的情况下更稳定。
四、空间复杂度分析
整个过程只用了常数级别的辅助变量(i
, j
等):
✅ 空间复杂度:O(1)
没有递归,没有辅助栈或结构,内存占用极低。
✅ 总结一句话
这段算法通过「右上角出发 + 单调缩减搜索空间」的策略,实现了 O(m+n) 的高效搜索,是最适合用于有序二维矩阵的面试技巧之一。相比于二分查找,这种方式更稳、更直观、更易推广。