【剑指offer】二维数组中的查找——复杂度为O(n+m)——采用PHP写法

背景

今天偶然进入牛客网,看到《剑指offer》模块有算法题,就开始试着答题

 

题目描述

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

一开始我的思路比较笨,不就直接遍历二维数组嘛?

输入以下代码提交了

<?php

function Find($target, $array)
{
    // write code here
    for($i = 0; $i < count($array[0]); $i++){
        for($j = 0; $j < count($array[1]); $j++){
            if($target === $array[$i][$j]){
                return 1;
            }
        }
    }
}

虽说第一次直接提交成功了,但是感觉好像这个时间复杂度有点高

仔细审了题,使用另外一种思路作答

思路:

  •  由于题目中的二维数组是有序排列的,而且是根据每一行从左到右递增,每一列从上到下递增,那么在查找二维数组的时候,可以通过这个规律来改变实现方法
  • 从每一个二维数组的左下角跟右上角开始查找比较方便(至于为什么方便,大家可以自己思考一下)

1、假设从右上角开始查找

          如果$target < $array[$i][$j],则往左边移动一个单位(即$j--);

          如果$target > $array[$i][$j],则往下边移动一个单位(即$i++);

          如果$target = $array[$i][$j],则返回true;

2、假设从左下角开始查找

          如果$target < $array[$i][$j],则往上边移动一个单位(即$i--);

          如果$target > $array[$i][$j],则往右边移动一个单位(即$j++);

          如果$target = $array[$i][$j],则返回true;

代码实现: 

<?php

function Find($target, $array)
{
    $length = count($array[0]);      //一维数组的长度
    $i      = 0;                     //起始横坐标
    $j      = $length - 1;           //起始纵坐标
    for($n = 0; $n < ($length - 1) + (count($array) - 1); $n++){ //最多移动$length减1 + 二维数组长度减1次
        if($array[$i][$j] === $target){//查找到目标,返回true
            return true;
        }
        if($array[$i][$j] < $target){//查找目标大于右上角元素,则$i++,下移
            $i++;
            continue;
        }
        if($array[$i][$j] > $target){//查找目标小于右上角元素,则$j--,左移
            $j--;
            continue;
        }
    }
}

代码讲解:

for循环中,最多只需要移动$length减1 + 二维数组长度减1 次,什么意思呢?

画个图你们就明白了

假设有如下二维数组:

我们从右上角开始查找22这个数 

由于22比8大,所以我们先下移,22比18大,我们继续下移,由于22比28小,我们需要左移......

最终我们移动了8次才找到22这个数,而且8次是移动次数最多的,为什么呢?

因为每一次只能下移或者左移,所以

左移次数最多6次(即一维数组长度减1次)

下移次数最多2次(即二维数组长度减1次)

这就是为什么for循环中,最多需要循环$length减1 + 二维数组长度减1次,$length就是一维数组的长度

因此这个算法的时间复杂度为O(n+m),其中n为一维数组的长度,m为二维数组的长度(忽略减去的2次) 

相比之前的O(n*m),还是快了些的。

总结 

牛客网真的是一个很不错的网址,上面不仅有大量的试题,而且还有很多大佬的经验分享,值得大家去好好利用这个资源,相信牛客网能给各位带来许多帮助,一起加油!

猜你喜欢

转载自blog.csdn.net/weixin_41463193/article/details/85346324