题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
首先看到这个题目我们可以想到举一个类似矩阵的例子,如下
通过观察这个例子我们可以看出,左上角的数字是最小的,右下角的数字是最大的,我们首先就要判断target是不是小于最小或者大于最大,是的话直接返回false
,以减少计算量。
再有就是如果target在两个数之间我们就要好好考虑一下该怎么做了。其实我们很简单就可以想到暴力遍历的方法,对每一行的数组进行判断,看看到底有没有target这个数字,有的话返回true,代码如下:
// 暴力遍历
function Find(target, array)
{
const row = array.length;
const col = array[0].length;
if(target < array[0][0] || target > array[row-1][col-1]){return false;}
for(let item of array){
if(item[0] > target){return false;}
if(item[col-1]>=target && item.includes(target)){
return true;
}
}
return false;
}
但是,这样子的话不是最优解,算法超时,我们就要想办法优化这个算法。
我们考虑如果从最左上角开始遍历,它的右边和下边都是比他它的数,所以我们不好进行遍历,我们的目标是要找一个数,它的两个分别是大于它的数和小于它的数,这样我们就可以通过遍历判断他是否包含target。从上图的矩阵中我们可以看到一个符合条件的数字,就是最左下角的数字4,比4大的数字在4的右边,比4小的数字在4的左边,这样我们就可以根据target的大小进行循环遍历,代码如下:
function Find(target, array)
{
const row = array.length;
const col = array[0].length;
if(target < array[0][0] || target > array[row-1][col-1]){return false;}
let x = row-1;
let y = 0;
while(true){
if(x<0 || y>=col){return false;}
if(target>array[x][y]){y++;}
else if(target<array[x][y]){x--;}
else{return true;}
}
}