二维数组中的查找
在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
0 <= array.length <= 5000 <= array[0].length <= 500
你能给出时间复杂度为O(n+m)的解法吗?(n,m为矩阵的长和宽)
方法一:暴力解法
时间复杂度:O(mn),因为我们在 n×m 矩阵上操作,总的时间复杂度为矩阵的大小
空间复杂度:O(1),暴力法分配的额外空间不超过少量指针,因此内存占用是恒定的
1 function Find(target, array) 2 { 3 // write code here 4 for(let i = 0;i<array.length;i++){ 5 for(let j = 0;j<array[i].length;j++){ 6 if(array[i][j]===target){ 7 return true; 8 break; 9 } 10 } 11 } 12 return false; 13 } 14 module.exports = { 15 Find : Find 16 };
方法二:坐标轴法+二分法
根据题意已知,二维数组从左往右递增,从上往下递增,所以得出以下结论:
某列的某个数字,该数之上的数字,都比其小;某行的某个数字,该数右侧的数字,都比其大;
所以,解题流程如下所示:以二维数组右上角为原点,建立直角坐标轴。若当前数字大于查找数,查找往上移一位。若当前数字小于查找数,查找往右移一位。
时间复杂度:O(n+m),访问到的下标的行最多增加n次,列最多减少m次,因此循环体最多执行n+m次
空间复杂度:O(1)
1 function Find(target, array) 2 { 3 // write code here 4 if(!array.length) {return false;} 5 let rows = array.length - 1, cols = 0; 6 while(rows >= 0 && cols <= array[0].length){ 7 if(array[rows][cols] === target){ 8 return true; 9 }else if(array[rows][cols]> target){ 10 rows--; 11 }else{ 12 cols++; 13 } 14 } 15 return false; 16 } 17 module.exports = { 18 Find : Find 19 };
方法三:数组扁平化+includes
Array.prototype.flat()方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。var newArray = arr.flat([depth])
Array.prototype.includes()方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false
1 function Find(target, array) 2 { 3 // write code here 4 return array.flat(Infinity).includes(target); 5 } 6 module.exports = { 7 Find : Find 8 };

浙公网安备 33010602011771号