zoukankan      html  css  js  c++  java
  • 用栈来求解hanoi塔问题

    题目来源:程序员算法面试指南,牛客网出品;

    第一种解法:递归法;

     1 //解法一:用递归法;
     2     public static int hanoi(int n, String left, String mid, String right){
     3         if(n<1){
     4             return 0;
     5         }
     6         return process(n, left, mid, right, left, right);
     7     }
     8     
     9     public static int process(int n, String left, String mid, String right, String from, String to){
    10         //n=1时,结束条件
    11         if(n==1){
    12             //from或to有一个是mid,只需移动1次
    13             if(from.equals(mid) || to.equals(mid)){
    14                 System.out.println("Move 1 from "+from+" to "+to);
    15                 return 1;
    16             } else{
    17                 //from和to都不是mid,需移动2次
    18                 System.out.println("Move 1 from "+ from + " to "+mid);
    19                 System.out.println("Move 1 from "+ mid + " to " + to);
    20                 return 2;
    21             }
    22         } 
    23         // n > 1,
    24         // from 或 to 有一个是mid, 只需移动一次;
    25         if(from.equals(mid)||to.equals(mid)){
    26             String another = (from.equals(left)||to.equals(left))? right : left;
    27             int part1 = process(n-1, left, mid, right, from, another);
    28             int part2 = 1;
    29             System.out.println("Move " + n +" from "+from+" to "+ to);
    30             int part3 = process(n-1, left, mid, right, another, to);
    31             return part1 + part2 + part3;
    32         }else{
    33             // from、to都不是mid, 共需移动5步
    34             int part1 = process(n-1, left, mid, right, from, to);
    35             int part2 = 1;
    36             System.out.println("Move "+ n +" from "+from +" to "+mid);
    37             int part3 = process(n-1, left, mid, right, to, from);
    38             int part4 = 1;
    39             System.out.println("Move "+ n +" from "+mid +" to "+to);
    40             int part5 = process(n-1, left, mid, right, from, to);
    41             return part1 + part2 + part3 + part4 + part5;
    42         }
    43     }

    第二种解法:用栈模拟

     1 //第二种解法
     2     //用栈模拟
     3     public static int hanoi(int n){
     4         Stack<Integer> LS = new Stack<Integer>();
     5         Stack<Integer> MS = new Stack<Integer>();
     6         Stack<Integer> RS = new Stack<Integer>();
     7         
     8         for(int i=n; i>0; i--)
     9             LS.push(i);
    10         
    11         int counter = 1;    //记录移动次数
    12         int last_step = 1;    //记录前一次移动,1:从左边移到中间,2:从中间移到左边,3:从中间移动到右边,4:从右边移动到中间
    13         MS.push(LS.pop());    //第一次,必须是左边往中间移动
    14         System.out.println("Move 1 from left to mid");
    15         
    16         while(RS.size() != n){
    17             for(int this_step=1; this_step<5; this_step++){    //步骤循环,判断哪种是正确的移动步骤,每次只有一种正确移法;
    18                 //当前步,不能跟上一步重复,也不能跟上一步相反(浪费移动步数)
    19                 if(this_step == last_step ||
    20                         this_step + last_step == 3 || this_step + last_step == 7)
    21                     continue;
    22                 switch (this_step){
    23                 case 1: //从左边移动到中间
    24                     if(LS.empty()) break;    //如果左边栈是空的,则不能进行移动
    25                     if(MS.empty() || LS.peek() < MS.peek()){    //如果中间栈为空,则不需要判断后边的,否则MS.peek()会报错
    26                         MS.push(LS.pop());
    27                         System.out.println("Move " + MS.peek() + " from left to mid.");
    28                         counter++;
    29                         last_step = this_step;    //当前步在下一次移动时成为上一步
    30                     }
    31                     break;
    32                 case 2:
    33                     if(MS.empty()) break;
    34                     if(LS.empty() || MS.peek() < LS.peek()){
    35                         LS.push(MS.pop());
    36                         System.out.println("Move " + LS.peek() + " from mid to left.");
    37                         counter ++;
    38                         last_step = this_step;
    39                     }
    40                     break;
    41                 case 3:
    42                     if(MS.empty()) break;
    43                     if(RS.empty() || MS.peek() < RS.peek()){
    44                         RS.push(MS.pop());
    45                         System.out.println("Move "+ RS.peek() + " from mid to right.");
    46                         counter ++;
    47                         last_step = this_step;
    48                     }
    49                     break;
    50                 case 4:
    51                     if(RS.empty()) break;
    52                     if(MS.empty() || MS.peek() > RS.peek()){
    53                         MS.push(RS.pop());
    54                         System.out.println("Move "+ MS.peek() + " from right to mid.");
    55                         counter++;
    56                         last_step = this_step;
    57                     }
    58                     break;
    59                 default:
    60                     System.out.println("step choice error!");
    61                 }
    62             }
    63         }
    64         return counter;
    65     }
  • 相关阅读:
    一起谈.NET技术,ASP.NET应用下基于SessionState的“状态编程框架”解决方案 狼人:
    一起谈.NET技术,谈谈ASP.NET皮肤机制的实现 狼人:
    一起谈.NET技术,asp.net控件开发基础(9) 狼人:
    一起谈.NET技术,asp.net控件开发基础(11) 狼人:
    一起谈.NET技术,ASP.NET MVC 3 Beta初体验之实用的WebMail 狼人:
    一起谈.NET技术,关于Silverlight战略转移新闻,我的思考 狼人:
    一起谈.NET技术,ASP.NET MVC 3 Beta初体验之超酷的Chart:3D效果 狼人:
    一起谈.NET技术,asp.net控件开发基础(10) 狼人:
    一起谈.NET技术,asp.net控件开发基础(19) 狼人:
    一起谈.NET技术,asp.net控件开发基础(8) 狼人:
  • 原文地址:https://www.cnblogs.com/HITSZ/p/7528915.html
Copyright © 2011-2022 走看看