1.题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
**注意:**给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
2.思路
这是一个简单的动态规划算法题。
F(1) = 1;
F(2) = 2;
F(3) = F(1)+F(2);
…
F(n) = F(n-1)+F(n-2);
由以上公式归纳,初次想到使用递归去解,即第n阶楼梯的爬法等于第n-1阶楼梯的爬法加上第n-2阶楼梯的爬法。
3.解法
public int climbStairs(int n) {
if(n==1)return 1;
if(n==2)return 2;
return climbStairs(n-1)+climbStairs(n-2);
}
以上解法耗时较长,在提交时显示超时了。
因为
F(n) = F(n-1)+F(n-2)
=F(n-2)+F(n-3)+F(n-3)+F(n-4) = F(n-2)+2F(n-3)+F(n-4)
=F(n-3)+F(n-4)+2(F(n-4)+F(n-5))+F(n-5)+F(n-6) = F(n-3)+3F(n-4)+3F(n-5)+F(n-6)
= …
那么我们需要想办法利用一下中间值,因为有部分相同的数值计算了多次。时间复杂度为
考虑第 i 级阶梯,第i级可以由第i-1阶走1步上来,也可以由第i-2阶走2步上来。
所以,新的解法为:
public int climbStairs(int n) {
if(n==1)return 1;
if(n==2)return 2;
//return climbStairs(n-1)+climbStairs(n-2);
int[] temResult = new int[n];
temResult[0]=1;temResult[1]=2;
for(int i=2;i<n;i++){
temResult[i] = temResult[i-1]+temResult[i-2];
}
return temResult[n-1];
}
动态规划问题
动态规划原理
1.确认原问题与子问题
原问题为球n阶台阶所有走法的数量,子问题是求1阶台阶、2阶台阶、…n -1阶台阶的走法。
2.确认状态,本地的动态规划状态单一,第 i 个状态即为 i 阶台阶的所有走法的数量。
3.确认边界状态的值。边界状态为1阶台阶与2阶台阶的走法,1阶台阶有1种走法,2阶台阶有2种走法,即 dp[1] = 1,dp[2] = 2.
4.确认状态转移方程。将求第 i 个状态的值转移为球第 i -1 个状态的值与第 i-2个状态的只,动态规划转移方程,
F(n) = F(n-1)+F(n-2);(n > 2)