爬楼梯

作者: 胡小菜 | 来源:发表于2019-02-09 16:26 被阅读0次

最近重拾leetcode的感觉,在工作之余添加点乐趣,决定以后每周刷4个题,尽量都更新上来,和大家一起分享,共同进步。以下为第一道题目。

题目描述:

假设你正在爬楼梯。需要n阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定n是一个正整数。

分析:

碰到这种类型的题目,最直接的方式就是从一个台阶开始解答,解答出一定数量的,发现答案其中的规律,形成公式,再编码实现。

1个台阶:1; 2个台阶:2;3个台阶:3;4个台阶:5;5个台阶:8........

从结论可以看出,自三个台阶开始,其方法数量等于前两个方法数量的和,即f(n) = f(n-1) + f(n-2) ,  这其实是个局部解,也许只是巧合,所以我们最好能够证明公式是对的。

当n >= 2时,走楼梯可以分两种情况爬楼:

第一种:第一步爬1个台阶,那么他们后面的爬楼方法数量是f(n-1);

第二种:第一步爬2个台阶,那么他们后面的爬楼方法数量是f(n-2);

所以f(n) = f(n-1) + f(n-2),ok,此时已经确认公式没有问题。

编码:

递归:

直观来看,使用递归方法很容易达成目标,实现如下:

    function climbStairs($n) {    

        if (!is_numeric($n) || $n < 0) {

            return;

        }

        if ($n == 1 || $n == 0) {

            return 1;

        }

        return $this->climbStairs($n-1) + $this->climbStairs($n-2);

    }

非递归:

递归的优点很明显,容易理解,代码总共也没多少行,缺点也很明显,中间楼梯重复计算耗时。

function climbStairs($n) {

    if (!is_numeric($n) || $n < 1) {

        return;

    }

    $result = [];

    for ($i=1; $i <= $n ; $i++) {

        if ($i > 2) {

            $result[$i] = $result[$i-1] + $result[$i-2];

        } else {

            $result[$i] = $i;

        }

    }

    return $result[$i-1];

}

该方法使用了空间换时间的方式,使用中间数组来存储中间台阶的结果,减少计算时间。

相关文章

网友评论

      本文标题:爬楼梯

      本文链接:https://www.haomeiwen.com/subject/ydlosqtx.html