002.爬楼梯

1.题目链接:

70. 爬楼梯

2.解题思路:

2.1.题目要求:

 给个阶数 n,要求返回爬完 n 阶有几种方法。

一次可以爬 1 步 或者 2 步。

示例 1
输入:n = 1 
输出:1
解释:有一种方法可以爬到楼顶。 
1. 1 阶

示例 2
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 3
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
示例 4
输入:n = 4
输出:5
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶 + 1 阶 
2. 1 阶 + 1 阶 + 2 阶
3. 1 阶 + 2 阶 + 1 阶
4. 2 阶 + 1 阶 + 1 阶
5. 2 阶 + 2 阶

2.2.思路:

根据示例1234,发现一个规律,n = 3 的方法总数 " 3 " n =2 和 n=1 的方法总数之和,n = 4 同理,所以推论,从 n = 3开始,后一项的方法总数是前两项方法总数之和。

注意 n = 0不存在因为不可能一阶楼梯没走就到一层了

1 2 3 5 8 类比斐波那契数列

2.3.动规五部曲:

2.3.1.确定dp数组以及下标的含义

dp[ i ] 的意思是,爬到第 i 层楼梯的时候,有 dp[ i ] 种爬法。

2.3.2.确定递推公式

推论,从 n = 3开始,后一项的方法总数是前两项方法总数之和。(注意 n = 0不存在)

及 dp[ i ] = dp[ i-1 ] + dp[ i-2 ]

2.3.3.dp数组如何初始化

n = 0 不存在的条件限制 dp数组,只能从i = 1 开始初始化。

所以初始化 dp[ 1 ] = 1 , dp[ 2 ] = 2 。

2.3.4.确定遍历顺序

由 dp[ i-1 ] , dp[ i-2 ] 这样的后两项,来推导 dp [ i ] 这样的前一项,所以遍历顺序由前向后遍历

2.3.5.举例推导dp数组

举例当n为5的时候,dp table(dp数组)应该是这样的

002.爬楼梯_第1张图片

如果代码出问题了,就把dp table 打印出来,看看究竟是不是和自己推导的一样。

2.4.总代码:

初始版

//版本一
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
        vector dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) { // 注意i是从3开始的
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

 

 优化版

// 版本二
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n;
        int dp[3];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            int sum = dp[1] + dp[2];
            dp[1] = dp[2];
            dp[2] = sum;
        }
        return dp[2];
    }
};

 

3.遇见的问题:

概念方向一开始好像混淆了一下。

4.记录:

重复的行为,不要期待有新的结果。(除了一些随机事件,一般不会突然醒悟..)

在家学,真是很大的挑战至少对我是这样的...

你可能感兴趣的:(动态规划——代码随想录,算法,动态规划,贪心算法)