持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
前言
力扣练习第二天,拒绝思路老化。今天要练习的是二维数组中的查找。
看看题目信息: 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
/**
* 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,return true。
* target = 20,return false。
*/
解法一
这道题,第一反应肯定是暴力法啦,对数组进行循环,对每个元素也进行循环,找到则return true,否则return false
var findNumberIn2DArray = function(matrix, target) {
for(let i = 0; i < matrix.length; i++) {
for(let j = 0; j < matrix[i].length; j++) {
if(matrix[i][j] === target) {
return true;
}
}
}
return false
};
两次循环,时间复杂度m*n,也就是O(n^2),太高了。能不能优化呢?答案是可以
解法二
仔细观察数组,我们会发现,二维数组的同一行元素,后一列都比前面的数值大,二维数组的同一列元素,后一行都比前面的数值大。啊,抱歉,题目信息也给出了,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序的信息。那么我们就不难得出这样的思路:
- 以二维数组左下角为原点,建立直角坐标轴。
- 若当前数字大于target,查找往上移一位。
- 若当前数字小于target,查找往右移一位。
图解呢推荐看这个二维数组中的查找
思路有了,代码很快也就出来了:
var findNumberIn2DArray = function(matrix, target) {
let i = matrix.length-1,j = 0;
while(i > -1 && j < matrix[0].length){
if(matrix[i][j] === target){
return true;
}else if(matrix[i][j] > target){
i--;
}else{
j++;
}
}
return false;
};
当然还有其他思路,二分查找,降维啊,个人认为都不如上述通俗易懂,所以在这也就不实现了。