leetcode 70. 爬樓梯問題(多種方法總結)
阿新 • • 發佈:2018-12-14
爬樓梯問題有多種出現形式,有不固定最多可跨階數(即最多可跨階數為M,M作為方法引數)的,有固定每次最多可跨2階的。接下來,我就對以上兩種出線形勢分別進行分析。
(一)固定每次最多跨越2階,使用非遞迴方式實現:
1、問題描述:
假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
注意:給定 n 是一個正整數。
2、首先我們把 n<=5 的不同情況列出來:
1 | 2 | 3 | 4 | 5 |
1 | 2 | 3 | 5 | 8 |
綜上我們可以看出,爬樓梯的方案數f(n) = f(n) + f(n-1)
3、我們用java程式碼實現以上思路:
class Solution {
public int climbStairs(int n) {
if(n==1||n==2){
return n;
}
int f1 = 1;
int f2 = 2;
int temp;
for(int i=3; i<=n; i++){
temp = f2;
f2 += f1;
f1 = temp;
}
return f2;
}
}
4、執行結果:
(二)使用遞迴方式實現
1、問題描述:
假設一個樓梯有 N 階臺階,人每次最多可以跨 M 階,求總共的爬樓梯方案數。
2、演算法實現(java語言):
private static int calculateCount(int ladder, int maxJump) { int jump = 0; if (ladder == 0) { return 1; } if (ladder >= maxJump) { // 剩下的樓梯大於最大可跳躍數 for (int i = 1; i <= maxJump; i++) { jump += calculateCount(ladder - i, maxJump); } } else { // 剩下的樓梯不足最大可跳躍數 jump = calculateCount(ladder, ladder); } return jump; }
(三)遞迴和非遞迴實現效能比較:
package test;
/**
*
* @author FHY
* 爬樓梯問題
*
*/
public class DynamicTest {
public static void main(String[] args) {
//對遞迴和非遞迴實現兩種方法進行效能比較:
long start = System.currentTimeMillis();
getNums(30);
long end1 = System.currentTimeMillis();
System.out.println("非遞迴實現:"+(end1-start));
calculateCount(30,2);
long end2 = System.currentTimeMillis();
System.out.println("遞迴實現:"+(end2-end1));
}
private static int calculateCount(int ladder, int maxJump) {
int jump = 0;
if (ladder == 0) {
return 1;
}
if (ladder >= maxJump) {
// 剩下的樓梯大於最大可跳躍數
for (int i = 1; i <= maxJump; i++) {
jump += calculateCount(ladder - i, maxJump);
}
} else {
// 剩下的樓梯不足最大可跳躍數
jump = calculateCount(ladder, ladder);
}
return jump;
}
public static int getNums(int n){
if(n==1||n==2){
return n;
}
int f1 = 1;
int f2 = 2;
int temp;
for(int i=3; i<=n; i++){
temp = f2;
f2 += f1;
f1 = temp;
}
long end = System.currentTimeMillis();
return f2;
}
}
輸出:
非遞迴實現:0
遞迴實現:14
可見,遞迴實現效能很差!