走臺階問題的動態規劃
阿新 • • 發佈:2019-02-03
題目要求:有一座高度為10級臺階的樓梯,從下往上走,每跨一步只能向上1級或者2級臺階。要求用程式來求出一共有多少種走法?
比如,每次走1級臺階,一共走10步,這是其中一種走法,我們可以簡寫成1,1,1,1,1, 1,1,1,1,1。、
這是一道典型的動態規劃類題目。我們很容易想到,當站在第10個臺階時,會回想剛才最後一步是咋上來的,無外乎兩種方式:一種是在第9個臺階上,然後輕鬆一步到第10個臺階;一種是在第8個臺階上,直接跨了兩個臺階,一步到第10個臺階。
然後繼續想要知道如何上到第9個或者第8個臺階呢?還是和前面思路一樣,分成一次走1步和一次走2步。。。就這樣層層遞迴,直到走到第1層和第0層臺階為止。所以:
number(走到第10個臺階)= number(走到第9個臺階) + number(走到第8個臺階)
對於這個公式,有一個很自然的想法,走的方法重複了?????
其實,並沒有,儘管走到第9個臺階的方法中,確實包含有走到第8個臺階的方法,但是由於登上第10階的最後一步不一樣,所以從整個過程來看,number(走到第9個臺階) 和 number(走到第8個臺階)還是不一樣的。這也就是說,按照一次走幾步類分類,可以把解集合無重疊、無混淆的分為兩個子集。
下面是自頂向下的遞迴實現,維護了一個HashMap來降低了時間複雜度
package others;
import java.util.HashMap;
public class StepProblem {
public static void main(String[] args) {
int n = 10;
HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
int number1 = step(n, h);
int number2 = step(n);
System.out.println("number1= " + number1 + " number2= " + number2);
}
//方法一:自頂向下
private static int step(int n, HashMap<Integer, Integer> h) {
// TODO Auto-generated method stub
if(n == 0) {
return 1;
}
if( n < 0) {
return 0;
}
if(h.containsKey(n)) {
return h.get(n);
} else {
int value = step(n - 1, h) + step(n - 2, h);
h.put(n, value);
return value;
}
}
//方法二,自底向上
private static int step(int n) {
int a = 1;
int b = 2;
int temp = 0;
for(int i = 3; i <= n; i++) {
temp = a + b;
a = b;
b = temp;
}
return temp;
}
}
逆轉思維,從底部向上,程式碼效率更高!