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

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

编写一个高效的算法来搜索 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. 搜索过程 (消去法):

使用 rowcol 指针,初始化为右上角元素的坐标(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. 题目假设的隐藏条件: 必须是 "二维排序矩阵",也就是每行每列都是排序好的。不然算法会失效。

三、结语

再见

相关推荐
c***V3232 小时前
Vue优化
前端·javascript·vue.js
李@十一₂⁰4 小时前
HTML 特殊字体符号
前端·html
小奶包他干奶奶6 小时前
Webpack学习——Loader(文件转换器)
前端·学习·webpack
zy happy6 小时前
若依 vue3 报错:找不到模块“@/api/xxxx/xxxxx”或其相应的类型声明。。Vue 3 can not find mod
前端·javascript·vue.js
mit6.8246 小时前
bfs|栈
算法
潘小安6 小时前
Git Worktree + Claude Code:让你的开发效率翻倍的秘密武器
前端
meichaoWen7 小时前
【Vue3】vue3的全面学习(一)
前端·javascript·学习
小猪努力学前端7 小时前
在 React + React Router v7 SSR 项目里做多端适配,我踩的两个坑
前端·react.js
q***d1737 小时前
React桌面应用开发
前端·react.js·前端框架
8***29317 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring