文章目录
-
- 一、题目简介
- 二、理解矩阵特性
- 三、思维导图
- 四、解法一:暴力遍历(Brute Force)
-
- 时间复杂度
- 空间复杂度
- 五、解法二:逐行二分查找
- 六、解法三:从右上角开始搜索(最优解)
-
- 核心思想
- 图解说明
- 执行过程示例
- Java 代码实现
- 复杂度分析
- 七、算法对比总结
一、题目简介
题目链接:搜索二维矩阵 II
题目描述:
给定一个 m × n m \times n m×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
二、理解矩阵特性
这个矩阵的排布有两个特点:
- 行递增:从左到右,数值变大。
- 列递增:从上到下,数值变大。
这意味着:
如果我们从右上角(或左下角)开始搜索,每次比较 target 与当前元素,能有方向性的缩小搜索范围。
三、思维导图
这是对不同解法思路的整体概览:
搜索二维矩阵 II
子问题分析
行列递增特性
二维有序
解法一 简单遍历
m*n
1
解法二 二分查找每行
对每一行做二分
m*log n
1
解法三 从右上角开始搜索
方向性剪枝
m+n
1
四、解法一:暴力遍历(Brute Force)
最直接的做法:
遍历每个元素,判断是否等于 target。
伪代码思想:
for each row in matrix:
for each col in row:
if element == target:
return true
return false
时间复杂度
- O ( m × n ) O(m \times n) O(m×n):扫描所有元素。
空间复杂度
- O(1):仅常量级辅助空间。
缺点:在大矩阵场景下效率极低,不推荐。
五、解法二:逐行二分查找
因为每一行都升序,可在每行内使用二分查找。
思路:
- 遍历每一行;
- 在该行中用二分法定位目标值。
流程图:
是
否
是
否
开始
遍历每一行
该行是否为空
二分查找该行
找到目标值?
返回 true
继续下一行
返回 false
复杂度分析
- 时间: O ( m × log n ) O(m \times \log n) O(m×logn)
- 空间:O(1)
优点: 较暴力法快。
缺点: 未充分利用列有序性。
六、解法三:从右上角开始搜索(最优解)
核心思想
从右上角开始看,如果当前元素大于目标值,则整列右侧都比它大,应往左走;如果当前元素小于目标值,则整行左侧都比它小,应往下走。
即:
- 当前元素比 target 大 → 剔除当前列;
- 当前元素比 target 小 → 剔除当前行。
图解说明
元素 > target
元素 < target
当前位置 matrix[0][n-1]
向左移动 col--
向下移动 row++
继续比较直到越界或找到元素
执行过程示例
以 target = 5 为例:
右上角起点值 11 → 比目标大 → 向左
到 7 → 比目标大 → 向左
到 4 → 比目标小 → 向下
到下一行 5 → 找到目标 → 返回 true
Java 代码实现
java
public class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int row = 0;
int col = n - 1;
while (row < m && col >= 0) {
int val = matrix[row][col];
if (val == target) {
return true;
} else if (val > target) {
col--; // 去左侧列
} else {
row++; // 去下方行
}
}
return false;
}
}
复杂度分析
- 时间复杂度:O(m + n),每次移动只缩减一行或一列。
- 空间复杂度:O(1),常数级额外空间。
优势:充分利用二维有序性,是该题理想解法。
七、算法对比总结
| 解法 | 思路说明 | 时间复杂度 | 空间复杂度 | 是否利用有序性 |
|---|---|---|---|---|
| 暴力遍历 | 逐个扫描 | O(m×n) | O(1) | 否 |
| 行二分查找 | 每行二分 | O(m×log n) | O(1) | 行有序 |
| 右上角搜索 | 剪枝搜索 | O(m+n) | O(1) | 行列均有序 |
综上,"右上角起点搜索"策略是该题的最优解法 ,兼顾效率与简洁性。
它巧妙地利用了二维有序结构的特性,不需要额外空间,能在一次线性扫描中完成搜索过程。