題目
一個人爬樓梯,他可以一次走1階或者2階,輸入不同的樓梯數,求有多少種不同的走法?
問題分析
從最後到達終點那階考慮,記爲F(n), 則到達F(n)有兩種情況, 從F(n-1)的位置,走1階到達; 從從F(n-2)的位置,走2階到達。所以 F(n) = F(n-1) + F(n-2); 即是fibonacci數列的情況。
優良算法
#include <stdio.h>
#include <iostream>
int climbStairs(int stairNumber)
{
if (1 == stairNumber)
{
return 1;
}
if (2 == stairNumber)
{
return 2;
}
int first = 1;
int second = 2;
int third = 0;
for(int i=3; i<=stairNumber; ++i)
{
third = first + second;
first = second;
second = third;
//std::cout<< third <<" ";
}
return third;
}
測試代碼:
int main(int argc, char* argv[])
{
for( int n=-3; n<=10; ++n)
{
std::cout <<"n="<< n << ": "
<< climbStairs(n) << std::endl;
}
return 0;
}
輸出結果:
複雜度分析
- 時間複雜度:O(n), 因爲只有一個單循環到n, 所以計算到第那個斐波那契數。
- 空間複雜度:O(1), 沒有使用任何數組或者矩陣之類的。常數級空間。
最優算法
- 求斐波那契數列的公式,直接帶公式
對應的C++ 代碼:
#include <stdio.h>
#include <iostream>
#include <cmath>
int climbStairs(int n)
{
if (n<0) return 0;
double sqrt5 = sqrt(5);
double fibn = pow((1+sqrt5)/2,n+1) - pow((1-sqrt5)/2,n+1); //注意是n+1
return (int)(fibn/sqrt5); //注意後面要加括號!
}
參考: https://leetcode-cn.com/problems/climbing-stairs/solution/pa-lou-ti-by-leetcode-solution/