用栈来求解汉诺塔问题

(一)、题目

汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有n层的时候,打印最优移动过程和最优移动总步数。

(二)、题目描述

在这里插入图片描述

(三)、样例

在这里插入图片描述

(四)、备注

在这里插入图片描述

(五)、程序代码(递归法)

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt();
        int step = sort(n,"left","mid","right","left","right");
        System.out.println("It will move "+step+" steps.");
    }
    public static int sort(int num,String left,String mid,String right,String from,String to) {
        if(num < 0) {
            return 0;
        }
        if(num == 1) {
            if(from.equals("mid") || to.equals("mid")) {
                System.out.println("Move "+ num + " from "+from+" to "+to);
                return 1;
            }else {
                System.out.println("Move "+ num + " from "+from+" to "+mid);
                System.out.println("Move "+ num + " 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 = sort(num-1,left,mid,right,from,another);
            System.out.println("Move "+ num + " from "+from+" to "+mid);
            int part2 = 1;
            int part3 = sort(num-1,left,mid,right,another,mid);
            return part1+part2+part3;
        }else {
            int part1 = sort(num-1,left,mid,right,from,to);
            System.out.println("Move "+ num + " from "+from+" to "+mid);
            int part2 = 1;
            int part3 = sort(num-1,left,mid,right,to,from);
            System.out.println("Move "+ num + " from "+mid+" to "+to);
            int part4 = 1;
            int part5 = sort(num-1,left,mid,right,from,to);
            return part1+part2+part3+part4+part5;
        }
    }
     
     
     
     
}

(六)、代码思路(递归法)

  1. 我尝试了一下往代码里加入注释,感觉不太好解释,我也就不班门弄斧了,这里直接贴上书上的解释吧,这样大家更好理解。
  2. 其实上面的代码也就是分为两种情况。一种是想从“左”移动到“中”,另一种是从“左”移动到“右”
    在这里插入图片描述

(七)、程序代码(非递归法)

import java.util.*;
public class Main {
    static Stack<Integer> ls = new Stack<Integer>();
    static Stack<Integer> ms = new Stack<Integer>();
    static Stack<Integer> rs = new Stack<Integer>();
     
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        int n = reader.nextInt();
        int step = sort(n);  
        System.out.println("It will move "+step+" steps.");
    }
     
    public static int sort(int num) {
        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);
        }
        int step = 0;
        Action[] record = {Action.No};
        while(rs.size()!= num+1) {
            step += process(record,Action.ltom,Action.mtol,ls,ms,"left","mid");
            step += process(record,Action.mtol,Action.ltom,ms,ls,"mid","left");
            step += process(record,Action.rtom,Action.mtor,rs,ms,"right","mid");
            step += process(record,Action.mtor,Action.rtom,ms,rs,"mid","right");
             
        }
        return step;
    }
     
    public static int process(Action[] record,Action pre,Action now,Stack<Integer> s1,Stack<Integer> s2,String from,String to) {
        if(record[0] != pre && s1.peek() < s2.peek()) {
            s2.push(s1.pop());
            System.out.println("Move "+ s2.peek() + " from "+from+" to "+to);
            record[0] = now;
            return 1;
        }
        return 0;
    }
}
enum Action {
    No,ltom,mtol,rtom,mtor
}

(八)、代码思路(非递归法)

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值