剑指offer[1]——二维数组中的查找

题目描述

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

首先看到这个题目我们可以想到举一个类似矩阵的例子,如下

通过观察这个例子我们可以看出,左上角的数字是最小的,右下角的数字是最大的,我们首先就要判断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;}
    }
}
我不管,JS天下第一
原文地址:https://www.cnblogs.com/Jacob98/p/12389293.html