版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010223904/article/details/46252915
github链接
本题leetcode链接
题目描述:
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Tags: Dynamic programming
题目分析:
题目是说现在你要爬一个有n个阶梯的楼梯,每次要么上一个阶梯,要么上两个阶梯。计算出所有可能的走法。
假设f(n)
表示的就是n个阶梯可能的走法的数量,第一次有两个选择,上一个阶梯或者两个阶梯,那么f(n) = f(n-2)+f(n-1)
。很眼熟,其实这就是斐波那契数的递归公式。基本情况就是
f(2) = 2(分两次,每次一步; 一次走两步)
f(1) = 1
斐波那契数的计算经常被用做讲解递归
的概念。很自然就想用递归实现。但是如果真的用递归实现,在leetcode上会得到Time Limit Exceeded
的错误。递归会带来大量的函数调用,函数调用时比如参数压栈,保存寄存器等等事情要花费不少时间,调用层次太深还会使方法栈溢出。不仅是这样,这道题的递归方案会做很多重复工作。
5
/\
3 4
/\ /\
1 2 2 3
/\
1 2
f(3)要计算两次, f(1)和f(2)因为是基本情况,这里感觉不到有很多的重复计算。如果n足够大,要重复计算的f(n)的数量是很大的。
所以使用题目的Tags提示的动态规划方法。用一个表记录之前计算过的f(n),这样使用迭代的方法就能实现这道题的算法。使用空间换时间。
代码实现(C):
//recusion implements cost too much time
//dynamic programming
//time VS space
int climbStairs(int n) {
int dp[n];
dp[0] = 1;
dp[1] = 2;
int i = 2;
while(i<n) {
dp[i] = dp[i-1]+dp[i-2];
i++;
}
return dp[n-1];
}