首先看下问题描述
给一个n表示n级台阶,而我们上台阶的方式有一次上1个台阶和一次上2个台阶,需要我们求出到n级台阶一共有多少种方法。
这题自然可以采用递归的方式,对于所到达的每级台阶,再次求其到第n级台阶的方法,具体实现类似如下伪代码:
GetWay(current_step, aim_step) {
int ways = 0;
if (current_step <= aim_step - 1) // 可以跨一级台阶
ways += 1 + GetWay(current_step + 1, aim_step);
if (current_step <= aim_step - 2) // 可以跨两级台阶
ways += 1 + GetWay(current_step + 2, aim_step);
return ways;
}
然而递归的时间复杂度总是客观的,换另外一种角度思考,这一个问题还可以通过动态规划解决。
为了求到第n级台阶可以有多少种方法,我们可以思考到第n级台阶的上一步是处于什么状态的:
- 处于n-1级台阶:此时可以通过跨一级台阶到达n级
- 处于n-2级台阶:此时可通过跨一级台阶到达n-1级,但这就不是到达n级台阶的上一步了,而是前两步,这里需要特别注意。所以此时只需讨论在n-2级台阶跨两级到达n级台阶
因此,到达第n级台阶的方法数可以通过处于n-1级状态的方法数+处于n-2级状态的方法数获得。由此可以解决本问题:
首先我们需要排除只有一级、两级台阶的情况:
设立数组ways,ways[i]表示到达第i级台阶的方法数,为了便于理解,将ways长度设为了n+1,放弃了ways[0]
此后对于第i级(i>2),其方法数都可以根据以下公式求得:
ways[i]=ways[i−1]+ways[i−2]
最后求得ways[n]即为答案。
具体代码如下:
int climbStairs(int n) {
if (n == 1)
return 1;
if (n == 2)
return 2;
int ways[n + 1];
ways[1] = 1;
ways[2] = 2;
for (int i = 3; i <= n; i++)
ways[i] = ways[i - 1] + ways[i - 2];
return ways[n];
}