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


七、结论与优化建议

  • 若矩阵规模较大且行列均递增,二分查找法是最优选择;
  • 对于需要实时搜索或数据不断更新的场景,可考虑双指针法;
  • 暴力法仅作为教学比对使用。
相关推荐
foundbug9991 小时前
果蝇优化算法(FOA)详解:原理、实现与应用
算法
游乐码1 小时前
c#递归函数
算法·c#
Pluchon1 小时前
硅基计划4.0 算法 简单实现B树
java·数据结构·b树·算法·链表
im_AMBER2 小时前
Leetcode 119 二叉树展开为链表 | 路径总和
数据结构·学习·算法·leetcode·二叉树
Eloudy2 小时前
SuiteSparse 的 README
人工智能·算法·机器学习·hpc
苏荷水2 小时前
万字总结LeetCode100(持续更新...)
java·算法·leetcode·职场和发展
gihigo19983 小时前
MATLAB运动估计基本算法详解
开发语言·算法·matlab
hetao17338373 小时前
2026-02-09~02-12 hetao1733837 的刷题记录
c++·算法
ADDDDDD_Trouvaille3 小时前
2026.2.12——OJ72-74题
c++·算法