一杯珍珠奶茶的时间吃透一道高频面试算法题——搜索二位矩阵Ⅱ

题目描述------搜索二位矩阵Ⅱ

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

示例 1:

lua 复制代码
输入: 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

示例 2:

lua 复制代码
输入: 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 = 20
输出: false

提示:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= n, m <= 300
  • -109 <= matrix[i][j] <= 109
  • 每行的所有元素从左到右升序排列
  • 每列的所有元素从上到下升序排列
  • -109 <= target <= 109

二、题解

js 复制代码
/**
 * 搜索二维排序矩阵
 *
 * @param {number[][]} matrix 二维排序矩阵
 * @param {number} target 目标值
 * @return {boolean} 如果目标值存在于矩阵中,则返回 true,否则返回 false
 */
var searchMatrix = function(matrix, target) {
    // 检查矩阵是否为空
    if (matrix.length === 0 || matrix[0].length === 0) {
        return false;
    }

    const m = matrix.length;           // 矩阵的行数
    const n = matrix[0].length;        // 矩阵的列数
    let row = 0;                       // 当前行索引,从第一行开始
    let col = n - 1;                   // 当前列索引,从最后一列开始

    while (row < m && col >= 0) {
        const current = matrix[row][col]; // 当前位置的值
        if (current === target) {
            // 找到了目标值,返回 true
            return true;
        } else if (current < target) {
            // 当前值小于目标值,需往下一行找
            row++;
        } else {
            // 当前值大于目标值,需往左一列找
            col--;
        }
    }

    // 搜索完整个矩阵,没有找到目标值,返回 false
    return false;
};

核心思想:

利用二维排序矩阵的特性,从右上角开始消去行或列,逐步逼近目标值。 类似于在一个有序空间中不断缩小搜索范围。

详细解释:

1. 矩阵排序特性:

(1)每一行从左到右递增。

(2)每一列从上到下递增。

2. 起始位置选择:

从矩阵的右上角元素 matrix[0][n-1] 开始搜索。这个位置的特殊性在于,其左边的元素都小于它,下边的元素都大于它。

3. 搜索过程 (消去法):

使用 row 和 col 指针,初始化为右上角元素的坐标(row = 0, col = n - 1)。

通过比较当前元素 matrix[row][col] 和目标值 target,决定下一步移动方向。

  • If matrix[row][col] === target :
    找到了目标值,返回 true。
  • If matrix[row][col] < target :
    当前元素小于目标值,由于当前元素所在列之上的所有元素都小于当前元素,因此可以排除当前列,row++,向下移动一行,继续搜索更大的值。
  • If matrix[row][col] > target :
    当前元素大于目标值,由于当前元素所在行的所有元素都大于当前元素,因此可以排除当前行,col--,向左移动一列,继续搜索更小的值。

4. 终止条件:

当 row 超出矩阵行数范围(row >= m)或者 col 超出矩阵列数范围(col < 0)时,搜索终止。

如果在整个搜索过程中都没有找到目标值,则返回 false。

易错点:

  1. 矩阵为空的判断 :
    如果矩阵为空(matrix.length === 0 || matrix[0].length === 0),应该直接返回 false,避免空指针异常或错误的计算。
  2. 起始位置的理解 :
    必须从右上角开始,从其他位置开始可能导致搜索方向错误或无法有效缩小搜索范围。
  3. 循环终止条件 :
    循环的条件必须是 row < m && col >= 0,确保在搜索过程中不超出矩阵的索引范围。 如果写反,可能会数组越界。
  4. 判断顺序 :需要优先判断 current === target,找到之后直接返回,可以有效减少运算。
  5. while循环的逻辑: row++, col-- 的位置不能写反。如果写反,会导致算法错误。
  6. row 和 col 的作用: row 是行索引, col 是列索引。理解这一点,才能正确决定是 row++ 还是 col--。
  7. 题目假设的隐藏条件: 必须是 "二维排序矩阵",也就是每行每列都是排序好的。不然算法会失效。

三、结语

再见

相关推荐
Chrischaan30 分钟前
做 AI 塔罗小程序时,我为什么不让大模型自己抽牌:一次上线复盘
前端
Peregrine931 分钟前
C++ - > 类和对象
java·c++·算法
骑着蜗牛撵大象3271 小时前
LangChain 工具调用从声明到闭环:给智能体接上真实的手脚
前端
数据掘金1 小时前
百度统计后台页面数据异常?从手动调用时机开始排查
前端
hunteritself1 小时前
10 层 4K 实时剪辑,国产工作站进入广电制作核心
大数据·前端·人工智能·深度学习·transformer
踩着两条虫1 小时前
我在浏览器里“盖”了一个村:Vue + Three.js 大屏开发踩坑记
前端·vue.js·three.js
mbshqqb1 小时前
TypeScript基础教程之同步生成器
前端·javascript·typescript
Gigavision1 小时前
DEAP数据集 2026最新Transformer算法 DEAP 数据集 下载
深度学习·算法·transformer
嘟嘟同学和妮妮同学2 小时前
【升级】一个中国历史可视化站:皇帝时间线梳理、古代思想流派、诗词鉴赏 (2)
前端·html
夜之眷属2 小时前
PriorityQueue:for-each 遍历和 poll 取出,顺序一样吗?
java·服务器·数据结构·后端·算法