Hot 100 --- 搜索二维矩阵
本文概览:本文讲解搜索二维矩阵的核心思路:利用矩阵完全递增的性质,通过两次二分查找快速定位目标值
一、题目

二、题目分析
这题的矩阵有一个关键性质:完全递增。
- 每行从左到右递增
- 下一行所有的数都比上一行大
- 按照"一行一行从左到右"的顺序遍历,所有数字是递增的
比如这个矩阵:
1 | 1 3 5 7 |
展开后就是 [1, 3, 5, 7, 10, 11, 16, 20, 23, 30, 34, 60],完全递增。
基于这个性质,我们可以采取两次二分查找的方法快速找到目标值:
- 第一次二分:确定 target 在哪一行
- 第二次二分:在确定的行内查找 target
思路概览
Java 实现代码如下
1 | public boolean searchMatrix(int[][] matrix, int target) { |
思路简要说明:
- 第一次二分:对行进行二分,判断 target 是否在当前行的范围内(
>= 第一个元素且<= 最后一个元素) - 第二次二分:在确定的行内,用标准的二分查找找 target
- 时间复杂度:O(log m + log n),m 是行数,n 是列数
三、思路详解
第一步:矩阵的关键性质
矩阵的关键性质是完全递增。这意味着:
- 每行的第一个元素是这一行的最小值
- 每行的最后一个元素是这一行的最大值
- 第 i 行的所有元素都小于第 i+1 行的所有元素
所以我们可以用每行的首尾元素来判断 target 是否在这一行:
1 | matrix[mid][0] <= target && matrix[mid][width-1] >= target |
第二步:第一次二分——确定行
对行进行二分查找,每次取中间行 mid,判断 target 是否在这一行的范围内:
- **
matrix[mid][0] <= target && matrix[mid][width-1] >= target**:target 在这一行,进入第二次二分 - **
matrix[mid][0] > target**:target 在这一行之前(上面的行),更新top = mid - 1 - **
matrix[mid][width-1] < target**:target 在这一行之后(下面的行),更新bottom = mid + 1
第三步:第二次二分——确定列
确定了行 row 之后,在这一行内用标准的二分查找找 target:
left = 0,right = width - 1mid = left + (right - left) / 2matrix[row][mid] == target:找到,返回 truematrix[row][mid] > target:target 在左边,right = mid - 1matrix[row][mid] < target:target 在右边,left = mid + 1
第四步:完整执行过程
以这个矩阵为例,target = 11:
1 | 1 3 5 7 |
第一次二分:确定行
1 | 初始:bottom=0, top=2 |
第二次二分:确定列
1 | 初始:left=0, right=3 |
再举一个找不到的例子,target = 13:
第一次二分:确定行
1 | 初始:bottom=0, top=2 |
第二次二分:确定列
1 | 初始:left=0, right=3 |
第五步:时间复杂度分析
- 第一次二分:对行进行二分,时间复杂度 O(log m),m 是行数
- 第二次二分:对列进行二分,时间复杂度 O(log n),n 是列数
- 总时间复杂度:O(log m + log n)
如果直接遍历整个矩阵,时间复杂度是 O(m × n)。二分查找的优势非常明显。
四、总结
搜索二维矩阵的核心是利用矩阵完全递增的性质,通过两次二分查找快速定位目标值:
- 第一次二分:确定 target 在哪一行(用每行的首尾元素判断范围)
- 第二次二分:在确定的行内查找 target
这个思路可以推广到所有"有序矩阵查找"类题目。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 青山木!

