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

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

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

三、结语

再见

相关推荐
全栈老李技术面试几秒前
【高频考点精讲】JavaScript中的访问者模式:从AST解析到数据转换的艺术
开发语言·前端·javascript·面试·html·访问者模式
独立开阀者_FwtCoder25 分钟前
狂收 33k+ star!全网精选的 MCP 一网打尽!!
java·前端·javascript
不会计算机的捞地44 分钟前
【数据结构入门训练DAY-21】信息学奥赛一本通T1334-围圈报数
算法
昔冰_G1 小时前
解锁webpack:对html、css、js及图片资源的抽离打包处理
前端·javascript·css·webpack·npm·html·打包
萌萌哒草头将军1 小时前
🚀 REST API 还是 ✈️ GraphQL ❓
前端·vue.js·react.js
小王努力学编程1 小时前
美团2024年春招第一场笔试 C++
开发语言·数据结构·c++·学习·算法
superior tigre1 小时前
C++学习:六个月从基础到就业——STL算法(一) 基础与查找算法
c++·学习·算法
刚入门的大一新生1 小时前
C++初阶-类和对象(下)
开发语言·c++·算法
just小千1 小时前
重学React(一):描述UI
前端·react.js·ui
fakaifa1 小时前
【最新版】沃德代驾源码全开源+前端uniapp
前端·小程序·uni-app·开源·php·沃德代驾·代驾小程序