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

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

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

三、结语

再见

相关推荐
Wyc724091 小时前
HTML:入门
前端·html
Sunny_lxm1 小时前
自定义列甘特图,原生开发dhtmlxgantt根特图,根据数据生成只读根特图,页面展示html demo
前端·html·甘特图·dhtmlxgantt
熊猫钓鱼>_>2 小时前
建筑IT数字化突围:建筑设计企业的生存法则重塑
前端·javascript·easyui
代码小将2 小时前
Leetcode209做题笔记
java·笔记·算法
Musennn3 小时前
leetcode 15.三数之和 思路分析
算法·leetcode·职场和发展
GISer_Jing4 小时前
前端性能指标及优化策略——从加载、渲染和交互阶段分别解读详解并以Webpack+Vue项目为例进行解读
前端·javascript·vue
不知几秋4 小时前
数字取证-内存取证(volatility)
java·linux·前端
水银嘻嘻5 小时前
08 web 自动化之 PO 设计模式详解
前端·自动化
CM莫问5 小时前
<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐
人工智能·算法·大模型·推荐算法·受限生成
康谋自动驾驶6 小时前
康谋分享 | 自动驾驶仿真进入“标准时代”:aiSim全面对接ASAM OpenX
人工智能·科技·算法·机器学习·自动驾驶·汽车