解决汉诺塔问题可以使用递归的方法,将最底下的一根柱子看成一个整体,上面n-1根柱子看成是另外一个整体。然后一直递归到0.
非递归版本貌似是用栈来完成,太菜了 目前还不会…
然后就是给定一个数组判断它是最优解的第几步。首先我们先看数组的最后一个元素,它只能在from或者是to的位置,因为最开始的时候是将其单独看成一个整体的,目标就是将其移动到to的位置,因此是不可能出现在mid位置。同理前面的元素也是这样的,因此可以一直递归下去。
package Demo01;
public class Demo02_HanoiProblem {
public static void moveOne(int n, String init, String desti){ //只有一个盘子的情况
System.out.println(" move:"+n+" from "+init+" to "+desti);
}
//递归版本
public static void hanoi(int n)
{
if(n > 0) func(n,"left","mid","right");
}
public static void func(int n, String from, String mid, String to){
if(n == 1){
moveOne(n, from, to);
}else{
func(n - 1,from, to , mid);
moveOne(n, from, to);
//func(1, from, mid, to);
func(n-1, mid, from, to);
}
}
//计算数组是最优解的第几步,如果没有就返回-1
public static int step1(int[] arr){
if(arr == null || arr.length == 0) return -1;
return process(arr, arr.length - 1, 1, 2, 3);
}
public static int process(int[] arr, int i,int from, int mid, int to){
if(i == -1) return 0;
if(arr[i] != from && arr[i] !=to){
return -1;
}
if(arr[i] == from){
return process(arr, i - 1, from, to, mid);
}else{
int rest = process(arr, i - 1, mid, from, to);
if(rest == -1){return -1;}
return (1 << i) + rest;
}
}
public static int step2(int[] arr){
if(arr == null || arr.length == 0) return -1;
int from = 1;
int mid = 2;
int to = 3;
int i = arr.length - 1;
int res = 0;
int tmp = 0;
while(i >= 0){
if(arr[i] != from && arr[i] != to){
return -1;
}
if(arr[i] == to){
res += 1 << i;
tmp = from;
from = mid;
}else{
tmp = to;
to = mid;
}
mid = tmp;
i--;
}
return res;
}
public static void main(String[] args) {
hanoi(4);
int[] arr = { 3, 3, 3, 3 };
System.out.println(step1(arr));
System.out.println(step2(arr));
}
}