二维数组中的查找

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]

给定 target = 7,返回 true。

给定 target = 3,返回 false。

0 <= array.length <= 500
0 <= 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 };

 

posted @ 2021-09-17 01:10  icyyyy  阅读(91)  评论(0)    收藏  举报