LeetCode Hot100(46/100)——74. 搜索二维矩阵

文章目录

📖 题目简述

给定一个 m x n 的二维矩阵,其中每一行的整数从左到右按升序排列,每一行的第一个整数都比前一行的最后一个整数大。
请编写一个高效算法,判断给定的目标值是否存在于矩阵中。


一、题目理解与特征分析

该二维矩阵在形式上可以视为一个"升序的一维数组":

复制代码
[
  [1, 3, 5, 7],
  [10, 11, 16, 20],
  [23, 30, 34, 60]
]

如果将整个矩阵展开为一维序列:

复制代码
[1, 3, 5, 7, 10, 11, 16, 20, 23, 30, 34, 60]

可以看到它实际上是一个从小到大的严格递增序列。

因此,我们可以利用二分查找思想在该"虚拟一维数组"中查找目标值。


二、解法总览

搜索二维矩阵
一维化二分查找
原理: 将二维矩阵视作一维递增数组
优点: 简洁高效, 时间复杂度O(log(m*n))
实现: 二分定位行列索引转换
行列方向双指针搜索
原理: 从右上角或左下角开始向目标逼近
优点: 思路直观,无需索引映射
实现: 根据大小移动行或列指针
暴力遍历
原理: 线性扫描所有元素
缺点: 时间复杂度高 O(m*n)


三、方法一:一维化二分查找(推荐)

原理说明

由于矩阵中的每行和每列都有严格的有序关系,可以将整个矩阵看成一个长度为 m * n 的一维递增数组,对其使用二分查找。

索引映射方式如下:

  • 行索引:row = mid / n
  • 列索引:col = mid % n

算法流程

否
是
相等
小于
大于
开始
初始化 left=0, right=m*n-1
left <= right?
返回false
计算 mid=(left+right)/2
计算 row=mid/n, col=mid%n
比较 matrixrowcol 与 target
返回true
left = mid + 1
right = mid - 1
结束

Java代码实现

java 复制代码
public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length;
        int n = matrix[0].length;
        int left = 0, right = m * n - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            int row = mid / n;
            int col = mid % n;
            int value = matrix[row][col];

            if (value == target) {
                return true;
            } else if (value < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        return false;
    }
}

时间复杂度分析

  • 时间复杂度 :O(log(m * n))
  • 空间复杂度 :O(1)

四、方法二:从右上角开始的双指针法

原理

  1. 从右上角元素开始(即第 0 行的最后一列)。
  2. 如果当前元素大于目标值,则向左移动(列减1)。
  3. 如果当前元素小于目标值,则向下移动(行加1)。
  4. 如果相等则返回 true。

动态过程示意图

Target Pointer Matrix Target Pointer Matrix alt 当前值 \> 目标 当前值 \< 目标 相等 选中右上角元素 比较当前值 向左移动 (col--) 向下移动 (row++) 返回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, col = n - 1;

        while (row < m && col >= 0) {
            int value = matrix[row][col];
            if (value == target) return true;
            else if (value > target) col--;
            else row++;
        }

        return false;
    }
}

时间复杂度分析

  • 时间复杂度 :O(m + n)
  • 空间复杂度 :O(1)

五、方法三:暴力法(仅作对比)

原理

  • 遍历矩阵中的每个元素,逐一与目标值比较。
    虽然能解决问题,但时间效率低。

Java实现

java 复制代码
public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == target) return true;
            }
        }
        return false;
    }
}

时间复杂度分析

  • 时间复杂度 :O(m * n)
  • 空间复杂度 :O(1)

六、思维框架总结

搜索二维矩阵思维框架
数据结构特性
行内升序
行间连续增大
解法思路
二分查找
映射为一维数组
双指针逼近
从右上角移动
线性遍历
暴力检测
复杂度对比
log m*n
m+n
m*n


七、结论与优化建议

  • 若矩阵规模较大且行列均递增,二分查找法是最优选择;
  • 对于需要实时搜索或数据不断更新的场景,可考虑双指针法;
  • 暴力法仅作为教学比对使用。
相关推荐
w_zero_one3 分钟前
算法--桶思想
java·开发语言·算法
wordbaby1 小时前
同一次请求里的两道锁:图解搞懂国密 SM2 与 SM3
算法
miller-tsunami2 小时前
内存管理&模板
c++·算法·内存管理·模板
青少儿编程课堂2 小时前
蓝桥杯青少组·全国青少年信息素养·电子学会Scratch考级:校园智能抢答器项目解析
c++·python·算法·bfs·信息学竞赛
SZYSK2 小时前
一套人员主数据,三套事务:通行、消费、人证比对如何分事件类型
物联网·算法·harmonyos
怕浪猫2 小时前
不用摄像机,我把历史故事做成竖屏视频
算法·面试·github
郝学胜-神的一滴3 小时前
AI 编程智能体 16:从零基础搭建到精细化优化
人工智能·python·算法·语言模型·langchain·pip
喜欢打篮球的普通人3 小时前
AI 编译器内存分配算法:从静态/动态划分到内存复用
人工智能·算法
晒太羊的猫4 小时前
hot100矩阵问题
线性代数·矩阵
mjhcsp4 小时前
Code date creation v8.0 竞赛数据生成与对拍实战指南
算法·ai·深度优先·cdc