难度:中等;
题目:
给你一个满足下述两条属性的 m x n
整数矩阵:
- 每行中的整数从左到右按非严格递增顺序排列。
- 每行的第一个整数大于前一行的最后一个整数。
给你一个整数 target
,如果 target
在矩阵中,返回 true
;否则,返回 false
。
示例 1:
lua
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
输出:true
示例 2:
lua
输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
输出:false
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 100
-104 <= matrix[i][j], target <= 104
解题思路:
可以通过使用二分查找的思想在一个二维矩阵中查找目标值。由于矩阵的每一行和每一列都是非严格递增的,并且每行的第一个元素都大于前一行的最后一个元素,我们可以将矩阵视为一个一维有序数组的组合。这就允许我们首先在行上应用二分查找,然后在选定的行上再次应用二分查找来定位目标值。
- 初始化 :定义两个指针
rowStart
和rowEnd
,分别初始化为矩阵的第一行(0)和最后一行(matrix.length - 1
)。 - 在行上二分查找 :在
rowStart
和rowEnd
之间进行二分查找,以找到可能包含目标值的那一行。如果target
大于中间行的首个元素并且小于等于中间行的末尾元素,或者target
大于中间行的下一个行的首个元素(如果存在),则在该行中查找target
。 - 在行内二分查找 :如果找到了可能包含目标值的行,对该行使用二分查找来确定
target
是否存在于该行中。 - 返回结果 :如果在某一行中找到了
target
,则返回true
;否则,如果所有行都未找到target
,则返回false
。
JavaScript代码实现:
ini
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix, target) {
let rowStart = 0;
let rowEnd = matrix.length - 1;
let rowMid; // 声明 rowMid 变量
// 二分查找合适的行
while (rowStart <= rowEnd) {
rowMid = Math.floor((rowStart + rowEnd) / 2); // 在循环内赋值
if (target >= matrix[rowMid][0] && target <= matrix[rowMid][matrix[rowMid].length - 1]) {
break;
} else if (target < matrix[rowMid][0]) {
rowEnd = rowMid - 1;
} else {
rowStart = rowMid + 1;
}
}
// 如果没找到合适的行,直接返回 false
if (rowStart > rowEnd) return false;
// 二分查找行内的元素
let colStart = 0;
let colEnd = matrix[rowMid].length - 1;
while (colStart <= colEnd) {
let colMid = Math.floor((colStart + colEnd) / 2);
if (matrix[rowMid][colMid] === target) {
return true;
} else if (matrix[rowMid][colMid] < target) {
colStart = colMid + 1;
} else {
colEnd = colMid - 1;
}
}
return false;
};
// 示例调用
// console.log(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 3)); // 输出: true
// console.log(searchMatrix([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]], 13)); // 输出: false