日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

左神算法:用栈来求解限制后的汉诺塔问题(Java版)

發(fā)布時間:2024/2/28 java 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 左神算法:用栈来求解限制后的汉诺塔问题(Java版) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本題來自左神《程序員面試代碼指南》“用棧來求解漢諾塔問題”題目。

題目

限制后的漢諾塔問題如下:

限制不能從最左側的塔直接移動到最右側,也不能從最右側直接移動到最左側,而是必須經過中間

求當塔有N層的時候,打印最優(yōu)移動過程和最優(yōu)移動總步數(shù)

題解

用以下兩種方法解決:

  • 方法1:遞歸方法。本文只提供代碼,具體的問題解析請參考原書。
  • 方法2:非遞歸,用棧來模擬漢諾塔的三個塔。本文詳細說明此方法。


代碼

為了便于理解,本文對 解法 2 做了詳細的注釋。

import java.util.Stack;public class Main {public static void main(String[] args) {int num = 4;// solution 1:遞歸解法int steps1 = hanoiProblem1(num, "left", "mid", "right");System.out.println("It will move " + steps1 + " steps.");System.out.println("===================================");// solution 2:非遞歸,用棧模擬整個過程int steps2 = hanoiProblem2(num, "left", "mid", "right");System.out.println("It will move " + steps2 + " steps.");System.out.println("===================================");}/*** 解法 1*/public static int hanoiProblem1(int num, String left, String mid,String right) {if (num < 1) {return 0;}return process(num, left, mid, right, left, right);}public static int process(int num, String left, String mid, String right,String from, String to) {if (num == 1) {if (from.equals(mid) || to.equals(mid)) {System.out.println("Move 1 from " + from + " to " + to);return 1;} else {System.out.println("Move 1 from " + from + " to " + mid);System.out.println("Move 1 from " + mid + " to " + to);return 2;}}if (from.equals(mid) || to.equals(mid)) {String another = (from.equals(left) || to.equals(left)) ? right : left;int part1 = process(num - 1, left, mid, right, from, another);int part2 = 1;System.out.println("Move " + num + " from " + from + " to " + to);int part3 = process(num - 1, left, mid, right, another, to);return part1 + part2 + part3;} else {int part1 = process(num - 1, left, mid, right, from, to);int part2 = 1;System.out.println("Move " + num + " from " + from + " to " + mid);int part3 = process(num - 1, left, mid, right, to, from);int part4 = 1;System.out.println("Move " + num + " from " + mid + " to " + to);int part5 = process(num - 1, left, mid, right, from, to);return part1 + part2 + part3 + part4 + part5;}}/*** 解法 2:重要*/public static enum Action {No, LToM, MToL, MToR, RToM}public static int hanoiProblem2(int num, String left, String mid, String right) {Stack<Integer> lS = new Stack<Integer>(); // 左棧Stack<Integer> mS = new Stack<Integer>(); // 中棧Stack<Integer> rS = new Stack<Integer>(); // 右棧lS.push(Integer.MAX_VALUE);mS.push(Integer.MAX_VALUE);rS.push(Integer.MAX_VALUE);for (int i = num; i > 0; i--) {lS.push(i);}Action[] record = {Action.No}; // 初始化 上一個動作為 No Actionint step = 0;while (rS.size() != num + 1) { // 每走一步,這4個動作只會有一個達標(不要誤解,這并不意味著每一次循環(huán)step只會+1,因為你走完一步之后,可能仍停留在當前這輪循環(huán)中),因此循環(huán)考察這4個動作即可step += fStackTotStack(record, Action.MToL, Action.LToM, lS, mS, left, mid); // 判斷當前是否可執(zhí)行 L->M 動作step += fStackTotStack(record, Action.LToM, Action.MToL, mS, lS, mid, left);step += fStackTotStack(record, Action.RToM, Action.MToR, mS, rS, mid, right);step += fStackTotStack(record, Action.MToR, Action.RToM, rS, mS, right, mid);}return step;}/*** 判斷當前動作是否可以執(zhí)行** @param record 實際的上一個動作* @param preNoAct 上一個動作不能是此動作* @param nowAct 當前要做的動作* @param fStack fromStack,當前欲從哪個棧彈出元素* @param tStack toStack,當前欲將彈出的元素壓入到哪個棧* @param from 從哪個棧(字符串),用于打印* @param to 到哪個棧(字符串),用于打印* @return 是否執(zhí)行了這一動作*/public static int fStackTotStack(Action[] record, Action preNoAct,Action nowAct, Stack<Integer> fStack, Stack<Integer> tStack,String from, String to) {if (record[0] != preNoAct && fStack.peek() < tStack.peek()) { // 同時滿足:(1)不可逆原則 && (2)小壓大原則tStack.push(fStack.pop()); // 執(zhí)行本次動作System.out.println("Move " + tStack.peek() + " from " + from + " to " + to);record[0] = nowAct;return 1;}return 0; // 不滿足兩原則,不執(zhí)行本次動作} }

總結

以上是生活随笔為你收集整理的左神算法:用栈来求解限制后的汉诺塔问题(Java版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。