Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。
题目描述
编写一个高效的算法来判断 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.length
- n == matrix[i].length
- 1 <= m, n <= 100
- -104 <= matrix[i][j], target <= 104
解法1
- arr.slice(-1)[0] 获取数组的最后一个值 效率比arr[arr.length-1]高
- 遍历每一行,判断值在第几行
- includes判断行里是否有target
var searchMatrix = function (matrix, target) {
let i = 0,
bool = false,
len = 0;
while (i < matrix.length) {
let arr = matrix[i];
let arr2 = matrix[i + 1];
if (arr[0] <= target && target <= arr.slice(-1)[0]) {
//值可能在第i行
bool = arr.includes(target);
if (bool) {
return bool;
}
}
i++;
}
return bool;
};
解法1 升级
- 用 inArr 替换 includes 方法,效率有显著提升
var searchMatrix = function (matrix, target) {
let i = 0,
bool = false,
len = 0;
while (i < matrix.length) {
let arr = matrix[i];
let arr2 = matrix[i + 1];
if (arr[0] <= target && target <= arr.slice(-1)[0]) {
//值可能在第i行
bool = inArr(arr,target);
if (bool) {
return bool;
}
}
i++;
}
return bool;
};
var inArr = function (arr, target) {
for (let i of arr) {
if (i == target) {
return true;
} else if (i > target) {
return false;
}
}
return false;
};
解法2 二分查询
如解法1,我们可以用二分法进阶,减小一半的便利
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function (matrix, target) {
let left = 0,
right = matrix.length - 1;
let bool = false;
while (left <= right) {
let mid = parseInt((left + right) / 2);
let arr = matrix[mid];
if (arr[0] <= target && target <= arr.slice(-1)[0]) {
let left2 = 0,
right2 = arr.length;
while (left2 <= right2) {
let mid2 = parseInt((left2 + right2) / 2);
if (arr[mid2] > target) {
//前半段
right2 = mid2 - 1;
} else if (arr[mid2] < target) {
left2 = mid2 + 1;
} else {
bool = true;
return bool;
}
}
return bool;
} else if (target < arr[0]) {
//前半段
right = mid - 1;
} else {
//后半段
left = mid + 1;
}
}
return bool;
};
解法3 最优解
- 从最后一行第0列开始遍历取值num
- 如果 target > num ,则表示 target 可能在当前行
- 如果 target < num ,则表示 target 可能不在当前行,取上一行第值再判断
- 如果想等返回 true,否则 false
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function (matrix, target) {
//获取中间的元素 比较大小
let i = matrix.length - 1, //行
j = 0; //列
while (i >= 0 && j < matrix[0].length) {
let num = matrix[i][j];
if (num == target) {
return true;
} else if (num < target) {
//上移动
j++;
} else {
i--;
}
}
return false;
};
总结
很简单的一道数学题,记录下,方便后期查阅