劍指offer之青蛙跳臺階
阿新 • • 發佈:2018-12-11
題目描述
一隻青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法(先後次序不同算不同的結果)。
求解思路
剛開始是想要通過遞迴模擬求解,結果超時了。但是這樣肯定能求出解來,不過計算了大量重複的程式碼,複雜度應該是指數級的。 正確的思路應該是:
- 先計算出最多能放幾個2步,假設是n個
- i從1到n,計算i個2步的情況下步法的組合數,所有組合數累加到sum上
- sum+1是最終解,因為全是1的情況也要考慮
複習排列組合的公式:
解題程式碼
#include <bits/stdc++.h>
using namespace std;
// 這是超時的,但是結果正確
class Solution_failed {
public:
int jumpFloor(int number) {
int sum = 0;
if(number == 0) {
return 1;
} else if(number < 0) {
return 0;
} else {
sum += jumpFloor(number - 1); // 跳一個
sum += jumpFloor(number - 2); // 跳兩個
return sum;
}
}
};
// 這是AC的程式碼,使用了階乘
class Solution {
public:
int jumpFloor(int number) {
// 只要確定了2步的位置,1步的位置隨便插入
int n = number / 2;
int sum = 1;
for(int i = 1; i <= n; ++i) {
// 注意,每增加一個2,總的空位置就要少一個,
int t = comp(number - i, i);
sum += t;
}
return sum;
}
// 計算組合數
int comp(int n, int k) {
long long up = 1, down = 1;
for(int i = n; i >= n - k + 1; i--) {
up *= i;
}
for(int j = k; j >= 1; j--) {
down *= j;
}
return up / down;
}
};
// 以下是測試
int main() {
Solution_failed sof;
Solution so;
for(int i = 1; i <= 10; ++i) {
// 輸出結果一致
cout << sof.jumpFloor(i) << "," << so.jumpFloor(i) << endl;
}
return 0;
}