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

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

编写一个高效的算法来搜索 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. 题目假设的隐藏条件: 必须是 "二维排序矩阵",也就是每行每列都是排序好的。不然算法会失效。

三、结语

再见

相关推荐
dialect_8 小时前
KMP算法
开发语言·c++·算法
reikocao8 小时前
卡尔曼滤波的动态机制:P如何改变融合权重
算法
jktantan8 小时前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
漂流瓶jz9 小时前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
夕除9 小时前
Redis 过期策略
redis·笔记·面试
吞下星星的少年·-·9 小时前
Div.2 CF 1130B题(构造,贪心)
算法·贪心·构造
2601_962885729 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
excel9 小时前
encodeURI 和 encodeURIComponent 有什么区别?
前端
前端精髓9 小时前
调用openrouter的免费API模型
java·前端·javascript
赛博守夜人10 小时前
AI安全攻防与治理之十四:AI 安全测试不能脱离传统安全,Web、API、移动端与模型攻击面的组合拳
前端·人工智能·安全