面试题 08.01. 三步问题 - 力扣(LeetCode)
1、状态表示:
题目要求:上到n阶台阶,有多少种方法。那么n逐渐简化,上1阶台阶有多少种方法;上2阶台阶有多少种方法……直到上n阶台阶有多少种方法。
那么,状态表示dp[i]:上n阶台阶有多少种方法。
2、状态转移方程:
上1阶台阶:从地面到1,0-》1。1种方法,dp[1] = 1
上2阶台阶:从地面到2,0-》2;或者从1到2,0-》1-》2。2两种方法,dp[2] = 2
上3阶台阶:0-》3;或者0-》1-》3;或者0-》1-》2-》3;或者0-》2-》3。4种方法。dp[3] = 4
上4阶台阶:1-》4;2-》4,3-》4。那么从1-》4,就先需要上1阶台阶,1种方法;从2-》4,就先需要上2阶台阶,2种方法;从3-》4,就先需要上3阶台阶,4种方法。一共dp[4] = 7,dp[4] = dp[1] + dp[2] + dp[3]。
……
那么,要想走到第i阶台阶,就有三种情况:从i-1直接到i,从i-2直接到i,从i-3直接到i。
那么求走到第i阶台阶的方法dp[i],就应该先知道dp[i-1],dp[i-2],dp[i-3],那么dp[i] = dp[i-1] + dp[i-2] + dp[i-3]。
3、初始化:
由状态转移方程可知,至少需要初始化前三个状态。
那么,地面可认为dp[0],那么dp[0]应该如何初始化呢?其实这里初始化0或1都没有关系,因为o0或1都可以解释得通。
我这里就初始化为1了。因为从0-》3,是一种方法,那么dp[3] = dp[0] + dp[1] + dp[2],方便写代码。
4、遍历顺序:
显然就是从左到右遍历。
5、返回值:
那么就是dp[n]。
class Solution {
public:int waysToStep(int n) {//越界检查if(n == 1 || n == 0) return 1;if(n == 2) return 2;const int MOD = 1e9 + 7;vector<int> dp(n+1);//创建dp表dp[0] = dp[1] = 1,dp[2] = 2;//初始化for(int i = 3;i<=n;i++)//遍历顺序dp[i] = ((dp[i-1] + dp[i-2])%MOD + dp[i-3])%MOD;//状态转移return dp[n];}
};
同样这里也可以用滚动数组优化。