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