有趣的演算法

星光辰枫發表於2024-04-10

126094-zui-yi_shu-shou_shi-ji_qie-chuang_zao_xing_de_yi_shu-1920x1080

青蛙跳臺問題

image-20240308161943909

現在一共有n個臺階,一隻青蛙每次只能跳一階或是兩階,那麼一共有多少種跳到頂端的方案?

例如n=2,那麼一共有兩種方案,一次性跳兩階或是每次跳一階。

現在請你設計一個Java程式,計算當臺階數為n的情況下,能夠有多少種方案到達頂端。

解決方法

假設青蛙已經站在了頂端(n),那麼它的前一個臺階是那個呢?要麼是第n-1階臺階,要麼是第n-2階臺階。

那麼到達第n階臺階所需的方案是不是就等於到達第n-1階臺階的方案數加上到達第n-2階臺階的方案數

即f(n) = f(n-1) + f(n-2)

Java實現程式碼

public static int steps(int n) {
    //判斷0臺階的情況
    if (n == 0) {
        return 0;
    }
    //判斷1階臺階的情況
    if (n == 1) {
        return 1;
    }
    //判斷2階臺階的情況
    if (n == 2) {
        return 2;
    }
    //遞迴呼叫
    return steps(n-1) + steps(n-2);
}

漢諾塔問題

img

漢諾塔(Tower of Hanoi),又稱河內塔,是一個源於印度古老傳說的益智玩具大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始

按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

問題:這三根柱子我們就依次命名為A、B、C,現在請你設計一個Java程式,計算N階(n片圓盤)漢諾塔移動操作的每一步。

解決方案

  • 只有一個圓盤的時候,可以直接把圓盤從A移到C(記作A--->C)

  • 當有兩個圓盤時,必須要把第一個移到B(A--->B),再把第二個移到C(A--->C),最後再把第一個圓盤從B移到C(B--->C)

  • 當有三個圓盤時...

    一個圓盤一個圓盤的考慮太複雜,那麼能不能只考慮只有兩部分的情況(最後一個圓盤(記作@)和除它之外的所有圓盤(記作#)),也就是相當於第二種情況。先把#移動到B柱(中間過程先不考慮),再把@移動到C柱。

    把@移動到C柱之後,以後所有的操作都在與它無關(暫時認為沒有它了),這時把B柱和A柱交換位置,那麼情況是不是又回到了(最後一個圓盤(記作@)和除它之外的所有圓盤(記作#))這種情況,我們重複上面的步驟。每重複一次,就相當於從剩餘需要移動的圓盤中挑出最大的扔掉,那麼最後又回到了只有一個圓盤的情況,那這不就好辦了嗎,直接把最後一個扔過去

    Java實現程式碼

    //把n個圓盤從A移到C
    public static void tower(int n, String a, String b, String c) {
        //只有一個圓盤的情況
        if (n == 1) {
            System.out.println(a + "--->" + c);
        } else {
            //把n-1個圓盤丟到B柱上
            tower(n-1, a, c, b);
            //把剩下的移到C柱上
            System.out.println(a + "--->" + c);
            //對於現在B柱上的圓盤,先把A柱和B柱交換位置,
            //問題就變成了把n-1個圓盤從A移動到C
            tower(n-1, b, a, c);
        }
    
    }
    

相關文章