用一个栈实现另一个栈的排序 & 用栈来求解汉诺塔问题
用一个栈实现另一个栈的排序
题目:用一个栈实现另一个栈的排序
《程序员代码面试指南》第5题 P12 难度:士★☆☆☆
该题题解的主要思路是申请2个栈,要排序的栈记为stack,辅助栈记为help,stack栈pop出的元素记为cur;
如果cur比help栈顶的元素小或相等,则压入help栈;否则,将help栈的元素逐一的压入stack栈,直到cur小于等于help栈顶元素,再将cur压入help栈。
一直执行以上操作,直到stack栈的全部元素都压入了help栈,最后再将help栈的所有元素全部压入stack栈,完成排序。
我自己想了半天没想出来这个完美的思路,我的思路就是2个栈互相压入,第一个栈保存每次pop出的最小值,第二个栈保存每次pop出的最大值;
执行5次,这个时候2个栈各自拥有原来一半的数据,最后再将第二个栈的数据全部压入第一个栈。
过程还是有点繁琐,涉及到:①每次pop时只能pop掉cnt-i+1(并且不超过cnt)个数据(底下的数据是已经排序号的从小到大或者从大到小的数据)
②每次pop在判断最值的时候,还得判断是否为上次的最值,是则直接丢弃,不过注意只能实现一次,不然会把其它相等的数也全部丢弃掉
③最后一步执行完,此时两个栈的栈顶是相同的,即有一个数据多余了,要把它pop并且丢弃掉
(光这么描述就感觉有多繁琐了┭┮﹏┭┮,当然我自己的思路也没必要再看,影响了正常题解的思路了)
自己的代码同样不贴了,太繁琐,以下是牛客网上的题解:
import java.util.Scanner;
import java.util.Stack;
public class Main {
//将栈中的元素排序
public static void sortStackByStatck(Stack<Integer> stack){
Stack<Integer> help = new Stack<Integer> ();
while (!stack.isEmpty()){
int cur = stack.pop();
while(!help.isEmpty() && help.peek() < cur) {
stack.push(help.pop());
}
help.push(cur);
}
while (!help.isEmpty()) {
stack.push(help.pop());
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Stack<Integer> stack = new Stack<Integer>();
while (n-- > 0) {
stack.push(sc.nextInt());
}
sortStackByStatck(stack);
while (!stack.isEmpty()){
System.out.print(stack.pop() + " ");//但是栈也变成一个空栈了
}
}
}
用栈来求解汉诺塔问题
题目:用栈来求解汉诺塔问题
《程序员代码面试指南》第6题 P13 难度:校★★★☆
该题虽然是校级难度,但是因为本科刘新华老师(膜拜)讲过汉诺塔问题,核心是使用递归来实现的。因此,本题虽是变种,但还是想了一会就想出来了。
该题在原来汉诺塔问题的基础上,加了限制条件:不能从最左端直接移动到最右端,必须先经过中间。从右到左亦是如此。
在看了书上的题解后,原来这个题目是有两种解法的,我也只想到了第一种,并且忽视了题目。第二种如题目所说,就是用栈来解决的。
由于牛客网上没有和书上相同的题解,这里放上自己的代码(除了繁琐点,核心思路是一样的):
import java.util.*;
public class Main {
private static StringBuilder sb = new StringBuilder();
private static Integer total = 0;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Integer cnt = Integer.parseInt(scan.nextLine());
leftToRight(cnt);
sb.append("It will move " + total + " steps.");
System.out.println(sb);
}
public static void leftToRight(Integer n) {
if(n > 1) {
leftToMid(n-1);
midToRight(n-1);
}
sb.append("Move " + n + " from left to mid\n");
total++;
if(n > 1) {
rightToMid(n-1);
midToLeft(n-1);
}
sb.append("Move " + n + " from mid to right\n");
total++;
if(n > 1) {
leftToMid(n-1);
midToRight(n-1);
}
}
public static void leftToMid(Integer n) {
if(n > 1) {
leftToMid(n-1);
midToRight(n-1);
}
sb.append("Move " + n + " from left to mid\n");
total++;
if(n > 1) {
rightToMid(n-1);
}
}
private static void midToRight(Integer n) {
if(n > 1) {
midToLeft(n-1);
}
sb.append("Move " + n + " from mid to right\n");
total++;
if(n > 1) {
leftToMid(n-1);
midToRight(n-1);
}
}
public static void rightToMid(Integer n) {
if(n > 1) {
rightToMid(n-1);
midToLeft(n-1);
}
sb.append("Move " + n + " from right to mid\n");
total++;
if(n > 1) {
leftToMid(n-1);
}
}
public static void midToLeft(Integer n) {
if(n > 1) {
midToRight(n-1);
}
sb.append("Move " + n + " from mid to left\n");
total++;
if(n > 1) {
rightToMid(n-1);
midToLeft(n-1);
}
}
}
完美代码请参见《程序员代码面试指南》P15
(非递归待更)

浙公网安备 33010602011771号