LeetCode 240. 搜索二维矩阵 II,为什么从右上角开始查找?

LeetCode 240. 搜索二维矩阵 II,为什么从右上角开始查找?

一、题目描述

给定一个矩阵:

  • 每一行从左到右递增
  • 每一列从上到下递增

判断目标值 target 是否存在于矩阵中。

示例:

python 复制代码
[
 [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]
]

查找:

python 复制代码
target = 5

返回:

python 复制代码
True

二、暴力搜索

最直接的方法:

遍历整个矩阵。

python 复制代码
for row in matrix:
    for num in row:
        if num == target:
            return True

复杂度:

python 复制代码
O(m*n)

虽然能做出来,但没有利用矩阵有序的特点。


三、为什么选择右上角?

矩阵具有两个方向的有序性:

python 复制代码
行:从左到右递增
列:从上到下递增

观察右上角:

python 复制代码
15

它有一个特殊性质:

  • 它是当前行最大值
  • 它是当前列最小值

因此可以一次排除一整行或一整列。


四、核心贪心思想

假设当前位置:

python 复制代码
cur = matrix[i][j]

情况1:找到目标

python 复制代码
cur == target

直接返回:

python 复制代码
True

情况2:当前值太大

python 复制代码
cur > target

例如:

python 复制代码
target = 10
cur = 15

因为这一列从上到下递增。

当前位置已经大于目标。

下面元素只会更大。

所以:

python 复制代码
这一整列都不可能有答案

直接左移:

python 复制代码
j -= 1

情况3:当前值太小

例如:

python 复制代码
cur = 7
target = 10

当前行左边更小。

肯定也不可能是答案。

所以:

python 复制代码
这一整行都可以排除

直接下移:

python 复制代码
i += 1

五、为什么不能从左上角开始?

左上角:

python 复制代码
1

如果:

python 复制代码
target = 5

你只知道:

python 复制代码
5 > 1

但:

python 复制代码
右边更大
下面也更大

不知道该往哪走。

无法排除区域。


六、右上角查找过程演示

查找:

python 复制代码
target = 5

开始:

python 复制代码
15

15 > 5

左移:

python 复制代码
11

11 > 5

继续左移:

python 复制代码
7

7 > 5

继续左移:

python 复制代码
4

4 < 5

下移:

python 复制代码
5

找到目标。

结束。


七、完整代码

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

        m = len(matrix)
        n = len(matrix[0])

        i = 0
        j = n - 1

        while i < m and j >= 0:

            cur = matrix[i][j]

            if cur == target:
                return True

            elif cur > target:
                j -= 1

            else:
                i += 1

        return False

八、复杂度分析

每一步:

  • 要么删除一整行
  • 要么删除一整列

因此:

最多移动:

python 复制代码
m + n

次。

时间复杂度:

python 复制代码
O(m+n)

空间复杂度:

python 复制代码
O(1)

九、高频易错点

1、循环条件写错

正确:

python 复制代码
while i < m and j >= 0

错误:

python 复制代码
j >= n - 1

会导致循环提前结束。


2、起点选错

正确:

python 复制代码
右上角

或:

python 复制代码
左下角

错误:

python 复制代码
左上角
右下角

无法确定唯一移动方向。


3、忘记处理空矩阵

必须先判断:

python 复制代码
if not matrix or not matrix[0]:

否则:

python 复制代码
matrix[0]

会直接报错。


十、一句话总结

这道题最关键的不是二分查找,而是利用矩阵行列同时有序的特点,从右上角开始,每次排除一整行或一整列,将搜索范围不断缩小,最终实现 O(m+n) 的高效查找。