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


七、结论与优化建议

  • 若矩阵规模较大且行列均递增,二分查找法是最优选择;
  • 对于需要实时搜索或数据不断更新的场景,可考虑双指针法;
  • 暴力法仅作为教学比对使用。
相关推荐
AI_Ming21 分钟前
从0开始学AI:层归一化,原来是这回事!
算法·ai编程
WL_Aurora27 分钟前
备战蓝桥杯国赛【Day 8】
算法·蓝桥杯
智者知已应修善业1 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
MediaTea1 小时前
Scikit-learn:从数据到结构——无监督学习的最小闭环
人工智能·学习·算法·机器学习·scikit-learn
智者知已应修善业1 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机
qeen871 小时前
【数据结构】二叉树相关经典函数C语言实现
c语言·数据结构·c++·笔记·学习·算法·二叉树
良木生香2 小时前
【C++初阶】STL——List从入门到应用完全指南(1)
开发语言·数据结构·c++·程序人生·算法·蓝桥杯·学习方法
WL_Aurora2 小时前
【每日一题】贪心
python·算法
aqiu1111112 小时前
【并查集专题top】
c++·算法
叼烟扛炮2 小时前
C++ 知识点17 友元
开发语言·c++·算法·友员