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
当前位置 matrix0n-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 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光2 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark2 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her12 天前
并查集-听课笔记
笔记·算法·并查集
码流子2 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven2 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark2 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218612 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法