汉诺塔问题

解决汉诺塔问题可以使用递归的方法,将最底下的一根柱子看成一个整体,上面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));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值