假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
根據規律可看出這其實是一個典型的斐波那契的問題,第n個數就是f(n) = f(n-1)+f(n-2);
我們必須找出以 1 和 2 作爲第一項和第二項的斐波那契數列中的第 n 個數,將f1 = 1;f2 =2初始化。
遞歸和非遞歸代碼如下:
//非遞歸
int climbStairs(int n)
{
if (n == 1)
{
return 1;
}
int first = 1;
int second = 2;
for (int i = 3; i <= n; i++)
{
int third = first + second;
first = second;
second = third;
}
return second;
}
//int climbStairs(int n)
//{
// if(n == 0)
// return 0;
// if(n == 1)
// return 1;
// if(n == 2)
// return 2;
// return climbStairs(n-2)+climbStairs(n-1);
//}
int main()
{
int n;
cin >> n;
cout << climbStairs(n) << endl;
}
此題也可以用動態規劃得出:
其實常規解法可以分成多個子問題,爬第n階樓梯的方法數量,等於兩部分之和
爬上 n−1 階樓梯的方法數量。因爲再爬1階就能到第n階
爬上 n−2 階樓梯的方法數量,因爲再爬2階就能到第n階
所以我們得到公式 dp[n]=dp[n−1]+dp[n−2]
同時需要初始化 dp[1] = 1和dp[2]=2
時間複雜度:O(n)
int climbStairs(int n)
{
if (n == 1) {
return 1;
}
int* dp = new int[n + 1];
dp[1] = 1;
dp[2] = 2;
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}