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) 行列均有序

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

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

相关推荐
机器学习之心2 小时前
MATLAB基于GA-ELM与NSGA-Ⅱ算法的42CrMo表面激光熔覆参数多目标优化
算法·matlab·ga-elm
FJW0208142 小时前
haproxy的调度算法
算法
浅念-2 小时前
C语言——内存函数
c语言·经验分享·笔记·学习·算法
MicroTech20252 小时前
微算法科技(NASDAQ:MLGO)基于后量子阈值算法的区块链隐私保护技术
科技·算法·区块链
qq_417129252 小时前
基于C++的区块链实现
开发语言·c++·算法
2401_832402752 小时前
C++中的命令模式实战
开发语言·c++·算法
有一个好名字2 小时前
力扣-钥匙和房间
算法·leetcode·深度优先
ZPC82102 小时前
ROS2 独占内核
人工智能·python·算法·机器人
老鼠只爱大米2 小时前
LeetCode经典算法面试题 #104:二叉树的最大深度(深度优先搜索、广度优先搜索等多种实现方案详细解析)
算法·leetcode·二叉树·dfs·bfs·深度优先搜索·广度优先搜索