暴力解法
int climbStairs(int n){
int solution = 0;
// 遞歸函數,返回值表示個數
int climb(int i,int n){
if(i > n){
return 0;
}
if( i == n){
return 1;
}
//轉移方程
return climb(i+1,n) + climb(i+2,n);
}
solution = climb(0,n);
return solution;
}
記憶化遞歸
- 例如上面的遞歸樹,有很多節點是算了好幾遍的(4,5)等等,我們可以用將他們記錄下來,避免再次遞歸計算。
- 個人有一個無奈的地方是記憶數組的初始化…但是不寫報錯,默認值根本不是0。
int climbStairs(int n){
int solution = 0;
int j;
// 二叉樹有n+1個非葉子節點
int memory[n+1];
for( j = 0; j < n+1; j++){
memory[j] = 0;
}
// 遞歸函數,返回值表示個數
int climb(int i,int n,int* memory){
// 葉子節點
if(i > n){
return 0;
}
if( i == n){
return 1;
}
// 記憶節點
if(memory[i] > 0){
return memory[i];
}
// 非葉子節點
memory[i] = climb(i+1,n,memory) + climb(i+2,n,memory);
//轉移方程
return memory[i];
}
solution = climb(0,n,memory);
return solution;
}
動態規劃
int climbStairs(int n){
if( n ==1 ){
return 1;
}
int dp[n+1];
int i ;
dp[1] = 1;
dp[2] = 2;
for( i =3; i <= n; i++ ){
dp[i] = dp[i-1] + dp[i - 2];
}
return dp[n];
}
參考
[ 1 ]官方解讀