「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。
题目
链接:leetcode-cn.com/problems/se…
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
- 每行中的整数从左到右按升序排列。
- 每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 输出: true
示例 2:
输入: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 输出: false
提示:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 100-104 <= matrix[i][j], target <= 104
解题思路
思路1
- 从矩阵左上角开始遍历,等于直接跳出,小于向左走一步n--,大于下走一步m++
- 循环后依旧执行1的操作,直到m,n不符合循环条件
代码
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix, target) {
if(matrix.length === 0) return false
let m = 0, n = matrix[0].length -1
// 1.从矩阵左上角开始遍历,等于直接跳出,小于向左走一步,大于下走一步
// 2.循环后依旧执行1的操作
while(m <= (matrix.length - 1)&& n>=0){
if(matrix[m][n] === target) return true
else if(target < matrix[m][n]){
n--
}else{
m++
}
}
return false
};
思路2
矩阵已经排好序了 左下角的位置特殊:上面的比它小,右边的比它大 选取左下角的位置开始遍历,如果当前数大了,上移一行;当前数小了,右移一列 找到返回true,遍历完返回false
代码
const searchMatrix = (matrix, target) => {
// 矩阵的行、列
const [m, n] = [matrix.length, matrix[0].length];
// (i,j)初始位置在左下角
let [i, j] = [m - 1, 0];
// 一直遍历到右上角位置
while (i >= 0 && j <= n - 1) {
if (matrix[i][j] > target) {
// 太大了,上移一行
i--;
} else if (matrix[i][j] < target) {
// 太小了,右移一列
j++;
} else {
// 找到,返回true
return true;
}
}
// 遍历完没找到,返回false
return false;
};
思路3
如果我们能把二维数组打平成一维数组,那就是套个二分法模板的事
剩下的问题是,怎么从一维数组的下标逆推二维数组的坐标?其实就是简单的数学计算。
我们将二维数组中的数字从左到右、从上到下,标记为第 0~(m x n) 个数字,用 pos 来表示。那么 pos 与数字在二维矩阵中坐标的关系如下:
x: floor(pos / cols)
y: pos % cols
- pos: 第 n 个数字
- cols: 二维矩阵的列数
代码
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function (matrix, target) {
if (!matrix || !matrix.length) return false;
const rows = matrix.length;
const cols = matrix[0].length;
let l = 0,
r = rows * cols - 1,
mid = 0;
while (l <= r) {
mid = ((l + r) / 2) << 0;
const [x, y] = getCoordFromPos(mid);
const num = matrix[x][y];
if (num < target) l = mid + 1;
else if (num > target) r = mid - 1;
else return true;
}
return false;
// *************************************
function getCoordFromPos(pos) {
const x = (pos / cols) << 0;
const y = pos % cols;
return [x, y];
}
};