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
比较 matrix[row][col] 与 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


七、结论与优化建议

  • 若矩阵规模较大且行列均递增,二分查找法是最优选择;
  • 对于需要实时搜索或数据不断更新的场景,可考虑双指针法;
  • 暴力法仅作为教学比对使用。
相关推荐
xianyinsuifeng几秒前
C语言性能优化实战:从 printf 到 write,再到批量输出(性能提升30%+)
算法
Halo_tjn1 分钟前
Java 内部类
java·开发语言·算法
开心码农1号4 分钟前
Go关于切边变量本身地址和内部指向地址
前端·算法
旖-旎4 分钟前
栈(验证栈序列)(5)
c++·算法·leetcode·力扣·
三毛的二哥5 分钟前
障碍物遮挡判断算法
人工智能·算法·计算机视觉·3d
啊我不会诶9 分钟前
2025ICPC南昌邀请赛vp补题
算法
发发就是发17 分钟前
I2C适配器与算法:从一次诡异的时序问题说起
服务器·驱动开发·单片机·嵌入式硬件·算法·fpga开发
啊哦呃咦唔鱼18 分钟前
leetcode二分查找
数据结构·算法·leetcode
郝学胜-神的一滴31 分钟前
[ 力扣 1124 ] 解锁最长良好时段问题:前缀和+哈希表的优雅解法
java·开发语言·数据结构·python·算法·leetcode·散列表
戴西软件32 分钟前
戴西CAxWorks.VPG车辆工程仿真软件|假人+座椅双调整 汽车仿真效率直接拉满
java·开发语言·人工智能·python·算法·ui·汽车