70.爬楼梯

70.爬楼梯

假设你正在爬楼梯。需要 《70.爬楼梯》 阶你才能到达楼顶。

每次你可以爬 《70.爬楼梯》《70.爬楼梯》 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 《70.爬楼梯》 是一个正整数。

示例 1:

输入: 《70.爬楼梯》
输出: 《70.爬楼梯》
解释: 有两种方法可以爬到楼顶。

  1. 《70.爬楼梯》 阶 + 《70.爬楼梯》
  2. 《70.爬楼梯》

示例 2:

输入: 《70.爬楼梯》
输出: 《70.爬楼梯》
解释: 有三种方法可以爬到楼顶。

  1. 《70.爬楼梯》 阶 + 《70.爬楼梯》 阶 + 《70.爬楼梯》
  2. 《70.爬楼梯》 阶 + 《70.爬楼梯》
  3. 《70.爬楼梯》 阶 + 《70.爬楼梯》

解答1

此题目可以说是最经典(另一种说法是最“容易”)的动态规划的题目。
动态规划是将一个大问题分解为多个简单的子问题来求解的方法。
动态规划常常适用于有重叠子问题与最优子结构的问题。

思路

  1. 《70.爬楼梯》为总的方法数量
  2. 可以看到,到第《70.爬楼梯》阶的方法其实一共有两种方式
    • 从第《70.爬楼梯》阶爬一步到达第《70.爬楼梯》
    • 从第《70.爬楼梯》阶爬两步到达第《70.爬楼梯》
  3. 因此可以总结出公式
    《70.爬楼梯》可以发现,这个就是斐波那契数列的变种。

代码1

java实现

class Solution {
    public int climbStairs(int n) {
        return resolve(n);
    }
    public int resolve(int n) {
        if (n==1) {
            return 1;
        }
        if (n==2) {
            return 2;
        }
        return resolve(n-1)+resolve(n-2);
    }
}

代码非常的简洁,马上丢到leetcode上跑一次,居然执行了10801 ms。击败了0.98%的人。。。

解法2

解法1虽然勉强能跑,但是有一个非常严重的问题是,重复计算量过大。
《70.爬楼梯》但是因为并没有暂存的地方,导致《70.爬楼梯》被计算了两次。
此时考虑到以往的数据会被重复使用,那么何不做一个数组暂存数据呢。

代码2

java实现

class Solution {
    public int climbStairs(int n) {
        int[] cache = new int[n+1];
        return resolve(n);
    }
    public int resolve(int n, int[] cache) {
        if (n==1) {
            return 1;
        }
        if (n==2) {
            return 2;
        }
        if (cache[n] ==0) {
            cache[n] = resolve(n-1,cache) +resolve(n-2,cache);
        }
        return cache[n];
    }
}

此方法4ms执行完成。

解法3

上述两种方法,均是递归调用,如何转为迭代呢?

代码3

java实现

class Solution {
    public int climbStairs(int n) {
        int[] cache = new int[n+1];
        cache[0] = cache[1] = 1;
        for(int i=2;i<=n;i++) {
            cache[i] = cache[i-1] + cache[i-2];
        }
        return cache(n);
    }
}
    原文作者:王可尊
    原文地址: https://www.jianshu.com/p/116fc5e57e43
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞