1. 程式人生 > 實用技巧 >漢諾塔解題思路

漢諾塔解題思路

漢諾塔解題思路

漢諾塔塔問題符合數學統計歸納,千萬別試圖去理解n層移動問題(或者說去理解n層遞迴,人腦真不夠用),理解3層漢諾塔問題就行。
總結起來如下:
遞迴的理解的要點主要在於放棄!放棄你對於理解和跟蹤遞迴全程的企圖,只理解遞迴兩層之間的交接,以及遞迴終結的條件。

解題演算法

  1. 如果A柱子只剩一個盤子,那麼直接移動到C柱子即可
  2. 把 n-1 號盤子移動到緩衝區
  3. 把1號從起點移到終點
  4. 然後把緩衝區的n-1號盤子也移到終點

解題框架

/*
1.要從a到b 那c就是緩衝 move(n-1,from,to,buffer)
2.要從a到c 那b就是緩衝 move(1,from,buffer,to)
3.要從b到c 那a就是緩衝 move(n-1,buffer,from,to)
*/ //漢諾塔移動框架 void move(n,from,buffer,to){ if (n == 1) { removeTo(from,to); return; } move(n-1,from,to,buffer); move(1,from,buffer,to); move(n-1,buffer,from,to); } void removeTo(List<Integer> from, List<Integer> to) { to.add(from.remove(from.size() - 1)); }

Java程式碼

//漢諾塔問題解釋https://www.zhihu.com/question/24385418
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
    remove(A.size(),A,B,C);
}
private void remove(int n, List<Integer> from, List<Integer> buffer, List<Integer> to) {
    //如果A柱子只剩一個盤子,那麼直接移動到C柱子即可
if (n == 1) { removeTo(from,to); return; } //1.把 n-1 號盤子移動到緩衝區 //把A柱子上面的n-1個盤子,藉助輔助柱子C,放到柱子B上 remove(n - 1, from, to, buffer); //2.把1號從起點移到終點 //此時A柱子剩下那個盤子是n個盤子中最大的那個,把他移動到C柱子上 remove(1, from,buffer,to); //3.然後把緩衝區的n-1號盤子也移到終點 //最後把剛才放在B柱子上的n-1個盤子,藉助柱子A輔助,放到柱子C上 remove(n - 1, buffer, from, to); } private void removeTo(List<Integer> from, List<Integer> to) { to.add(from.remove(from.size() - 1)); }