力扣hot100-240.搜索二维矩阵2-单调性剪枝详解

LeetCode 240. 搜索二维矩阵 II:单调性剪枝详解

1. 算法思想

这题属于:

text 复制代码
矩阵搜索 / 单调性剪枝

也常被称为 Z 字形搜索。它不是普通二分查找:每一行、每一列分别有序,但整个矩阵按行展开后并不整体有序。

例如:

text 复制代码
[
  [1, 4, 7],
  [2, 5, 8],
  [3, 6, 9]
]

按行展开是 1, 4, 7, 2, 5, 8, 3, 6, 9,其中 7 后面是 2,因此不能把它当一维数组二分。

本题的关键是:从右上角开始,每次比较都能确定排除一整行或一整列。

2. 为什么从右上角开始

右上角 matrix[0][n - 1] 有两个相反的单调方向:

text 复制代码
左边都更小。
下面都更大。

因此当前位置 matrix[row][col]target 比较后,移动方向是确定的:

text 复制代码
current > target:向左,排除当前列。
current < target:向下,排除当前行。
current == target:找到答案。

当前值过大,为什么排除当前列

如果:

text 复制代码
current > target

当前列从上到下递增。从当前行往下的元素都满足:

text 复制代码
matrix[i][col] >= current > target

整列都太大,不可能有答案,因此:

java 复制代码
col--;

当前值过小,为什么排除当前行

如果:

text 复制代码
current < target

当前行从左到右递增。当前剩余区域中,这一行从左边界到当前列的所有元素都满足:

text 复制代码
matrix[row][j] <= current < target

整行都太小,不可能有答案,因此:

java 复制代码
row++;

3. 用 target = 5 完整模拟

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

从右上角开始:

text 复制代码
row = 0, col = 4,当前值 15
15 > 5,向左。

row = 0, col = 3,当前值 11
11 > 5,向左。

row = 0, col = 2,当前值 7
7 > 5,向左。

row = 0, col = 1,当前值 4
4 < 5,向下。

row = 1, col = 1,当前值 5
找到目标。

路径是:

text 复制代码
15 -> 11 -> 7 -> 4
                   |
                   v
                   5

因此这类搜索也叫 Z 字形搜索。

4. 为什么不会漏掉答案

当前位置始终是当前剩余区域的右上角。

text 复制代码
当前值大于 target:当前列下面的值更大,整列排除安全。
当前值小于 target:当前行左边的值更小,整行排除安全。

每一步删除的都是确定不可能包含 target 的区域。搜索会在找到目标,或剩余区域为空时结束,因此不会漏掉答案。

5. Java 代码完整注释

java 复制代码
class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        // 空矩阵中不存在目标。
        if (matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }

        int m = matrix.length;
        int n = matrix[0].length;

        // 从右上角开始。
        int row = 0;
        int col = n - 1;

        // row 只向下移动,col 只向左移动。
        // 任一指针越界时,说明剩余区域为空。
        while (row < m && col >= 0) {
            int current = matrix[row][col];

            if (current == target) {
                return true;
            }

            if (current > target) {
                // 当前列从上到下递增,下面的元素只会更大。
                // 所以当前列不可能有 target,向左排除它。
                col--;
            } else {
                // 当前行从左到右递增,左边的元素只会更小。
                // 所以当前行不可能有 target,向下排除它。
                row++;
            }
        }

        return false;
    }
}

6. 左下角也可以

左下角同样有相反的单调方向:上面更小,右边更大。

因此从左下角开始也可以:

text 复制代码
当前值大于 target:向上。
当前值小于 target:向右。

它与右上角写法本质相同。学习时固定记住右上角版本即可:

text 复制代码
大了向左,小了向下。

7. 复杂度分析

每一步只会向左移动一列,或者向下移动一行。

text 复制代码
最多向左 n 次。
最多向下 m 次。

所以时间复杂度是:

text 复制代码
O(m + n)

额外空间复杂度是:

text 复制代码
O(1)

8. 总结

这题属于矩阵搜索 / 单调性剪枝。

从右上角开始:

text 复制代码
当前值 > target:当前列全都太大,向左。
当前值 < target:当前行全都太小,向下。

每一步排除一整行或一整列,因此效率是 O(m + n)

一句话记忆:

text 复制代码
从右上角开始:大了向左,小了向下。
相关推荐
imuliuliang1 小时前
关于基于图论的最短路径算法性能对比分析7
算法
雨落在了我的手上1 小时前
Java数据结构(九):栈和队列
java·开发语言·数据结构
imuliuliang1 小时前
关于从栈与队列看算法思维的演化路径7
算法
春生野草2 小时前
个人笔记--大顶堆和基数排序
java·数据结构·算法
白狐_7982 小时前
【408计算机网络|第04章·下|408-CN-04B】网络层(下):路由算法、RIP、OSPF、BGP、IPv6与路由器
计算机网络·算法·智能路由器
皓月斯语2 小时前
B3865 [GESP202309 二级] 小杨的 X 字矩阵 题解
开发语言·c++·矩阵·题解
donoot3 小时前
PaddleOCR + PyMuPDF 生成【全兼容双层 PDF】完整实操指南
人工智能·算法·pymupdf·paddleocr·双层pdf
paeamecium4 小时前
【PAT甲级真题】- Rational Sum (20)
数据结构·c++·python·算法·pat考试·pat
奋发向前wcx10 小时前
y1,y2总复习笔记10 2026.7.24
笔记·哈希算法·散列表