LeetCode Hot100(17/100)——240. 搜索二维矩阵 II

文章目录

    • 一、题目简介
    • 二、理解矩阵特性
    • 三、思维导图
    • 四、解法一:暴力遍历(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):仅常量级辅助空间。

缺点:在大矩阵场景下效率极低,不推荐。


五、解法二:逐行二分查找

因为每一行都升序,可在每行内使用二分查找。

思路:

  1. 遍历每一行;
  2. 在该行中用二分法定位目标值。

流程图:




开始
遍历每一行
该行是否为空
二分查找该行
找到目标值?
返回 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) 行列均有序

综上,"右上角起点搜索"策略是该题的最优解法 ,兼顾效率与简洁性。

它巧妙地利用了二维有序结构的特性,不需要额外空间,能在一次线性扫描中完成搜索过程。

相关推荐
野犬寒鸦27 分钟前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总29 分钟前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
rainbow688936 分钟前
深入解析C++STL:map与set底层奥秘
java·数据结构·算法
wangjialelele1 小时前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先
驱动探索者1 小时前
linux mailbox 学习
linux·学习·算法
ringking1231 小时前
autoware-1:安装环境cuda/cudnn/tensorRT库函数的判断
人工智能·算法·机器学习
大闲在人2 小时前
8. 供应链与制造过程术语:产能
算法·制造·供应链管理·智能制造·工业工程
一只小小的芙厨2 小时前
寒假集训笔记·以点为对象的树形DP
c++·算法
历程里程碑2 小时前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
执风挽^2 小时前
Python基础编程题2
开发语言·python·算法·visual studio code