这是一道比较比较复杂的问题,完全写下来会非常浪费时间,具体分析过程参见《程序员代码面试指南》。后面如果我有时间,就补充一下。
思路一:递归
import java.util.Scanner;
public class Main{
public static int hanoiProblem(int num){
if (num < 1) {
return 0;
}
String left = "left";
String mid = "mid";
String right = "right";
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 " + mid);
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") || from.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;
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int count = hanoiProblem(num);
System.out.println("It will move " + count + " steps.");
}
}
思路二:利用栈来实现
import java.util.Scanner;
import java.util.Stack;
enum Action {
No, LtoM, MtoL, RtoM, MtoR
}
public class Main {
public static int hanoiProblem2(int num) {
String left = "left";
String right = "right";
String mid = "mid";
Action[] record = {Action.No};
int step = 0;
Stack<Integer> lS = new Stack<>();
Stack<Integer> mS = new Stack<>();
Stack<Integer> rS = new Stack<>();
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);
}
while (rS.size() != num + 1) {
step += fStackTotStack(record, Action.MtoL, Action.LtoM, lS, mS, left, mid);
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;
}
public static int fStackTotStack(Action[] record, Action preNoAct, Action nowAct,
Stack<Integer> fStack, Stack<Integer> tStack,
String from, String to) {
if (preNoAct != record[0] && fStack.peek() < tStack.peek()) {
tStack.push(fStack.pop());
System.out.println("Move " + tStack.peek() + " from " + from + " to " + to);
record[0] = nowAct;
return 1;
}
return 0;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int step = hanoiProblem2(num);
System.out.println("It will move " + step + " steps.");
}
}