我们用 f(x) 表示爬到第 x 级台阶的方案数,考虑最后一步可能跨了一级台阶,也可能跨了两级台阶,所以我们可以列出如下式子(类似于斐波那契数列)
f(x) = f(x - 1) + f(x - 2)
它意味着爬到第 x 级台阶的方案数是爬到第 x - 1 级台阶的方案数和爬到第 x - 2 级台阶的方案数的和,很好理解,因为每次只能爬 1 级或 2 级,所以 f(x) 只能从 f(x - 1) 和 f(x - 2) 转移过来,而这里要统计方案总数,我们就需要对这两项的贡献求和
p、q、r类似于滚动数组一样在工作
class Solution
{
public:
int climbStairs(int n)
{
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i)
{
p = q;
q = r;
r = p + q;
}
return r;
}
};
int main()
{
Solution A;
cout << A.climbStairs(5) << endl;
return 0;
}
时间复杂度:循环执行 n 次,每次花费常数的时间代价,故渐进时间复杂度为 O(n)
空间复杂度:这里只用了常数个变量作为辅助空间,故渐进空间复杂度为 O(1)
这种方法也可以,不过随着n的值增大,递归的次数也在不断的增加,会导致运行超时
class Solution
{
public:
long long int climbStairs(int n)
{
if (n == 1)
return 1;
else if (n == 2)
return 2;
else
return climbStairs(n - 1) + climbStairs(n - 2);
}
};
int main()
{
Solution A;
cout << A.climbStairs(5) << endl;
return 0;
}