JAVA-爬樓梯

題目:

有一座高度是10級臺階的樓梯,從下往上走,每跨一步只能向上1級或者2級臺階,要求用程序來求出一共有多少種走法?

例子,每次走1級臺階,一共走10級臺階,這是其中一種走法,我們可以簡寫成 1,1,1,1,1,1,1,1,1,1

解題思路:

假設你只差最後一步走到10級臺階,這時候會出現幾種情況?
這時只會出現兩種情況,

  • 第一種:最後一步走1級臺階,第一種情況對應的是已經走到了第9級臺階
  • 第二種:最後一步走2級臺階,第二種情況對應的是已經走到了第8級臺階

此時並不具體考慮如何走到第9或者第8級臺階的

假設走到第10級臺階的走法有F(10)
則走到第9級臺階的走法有F(9)
則走到第8級臺階的走法有F(8)
則F(10)=F(9)+F(8)
由題意可知
F(1)=1
F(2)=2

解法一:常規的迭代算法

public static int getClimbingWays(int n) {
        if (n < 1) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        return getClimbingWays(n - 1) + getClimbingWays(n - 2);
    }

存在的問題:

此計算過程類似一顆二叉樹,頂點是F(10),左右子節點是F(9)和F(8),依次計算下去,這個二叉樹層高10-1,節點個數2^10-1,
時間複雜度近似O(2^n)
這一顆計算二叉樹中有許多重複的計算部分, 在這裏插入圖片描述
這些重複的部分事實上我們可以採用緩存將其保存起來

解法二:採用緩存的方式,以降低時間複雜度

具體實現如下:

public static int getClimbingWaysCache(int n, HashMap<Integer, Integer> map) {
        if (n < 1) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        if (map.containsKey(n)) {
            return map.get(n);
        } else {
            Integer value = getClimbingWays(n - 1) + getClimbingWays(n - 2);
            map.put(n, value);
            return value;
        }
    }

在以上代碼中,集合map是一個緩存。當每次需要計算F(N)的時候,會首先從map中尋找匹配元素。如果map中存在,就直接返回結果,如果map中不存在,就計算出結果,存入緩存中。
此時時間複雜度:O(n),需要計算F(10),F(9),。。。這些數字
此時空間複雜度:O(n),需要保存F(10),F(9),.。。。F(3),由於F(1)和F(2)都是已知的不需要緩存在備忘錄中

問題

這種方法中所需要的空間複雜度爲O(n),這種計算方法採用的自頂向下的計算方式,所以必須保存每次計算的結果,以便後期取用。如何降低空間複雜度?

解法三:採用自底向上算法,以降低空間複雜度

實現

 public static int getClimbingCacheCacheImp(int n) {
        if (n < 1) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        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;
    }

程序從 i=3 開始迭代,一直到 i=n 結束。每一次迭代,都會計算出多一級臺階的走法數量。迭代過程中只需保留兩個臨時變量a和b,分別代表了上一次和上上次迭代的結果,最後的結果由temp保存。
此時時間複雜度:O(n),需要計算F(10),F(9),。。。這些數字
此時空間複雜度:O(1),需要保存a,b,temp,所需空間爲3(常量)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章