1,设计一个有getMin功能的栈

题目:实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中的最小值
要求:
1,pop、push、getMin操作的时间复杂度都是O(1)
2,设计的栈类型可以使用现成的栈的结构
public class Stack1 {
    private Stack<Integer> stackMin;
    private Stack<Integer> stackData;


    public Stack1(){
        stackMin=new Stack<>();
        stackData=new Stack<>();
    }

    public int getMin(){
        if(stackMin.isEmpty()){
            throw new RuntimeException("stack is null");
        }
        return stackMin.peek();
    }

    //方案一
    //节省空间,pop步骤多
    public void push(int newNum){
        if(stackMin.isEmpty()){
            stackMin.push(newNum);
        }else{
            if(getMin()<=newNum){
                stackMin.push(newNum);
            }
        }
        stackData.push(newNum);
    }

    public int pop(){
        if(stackData.isEmpty()){
            throw new RuntimeException("stack is null");
        }
        int value=stackData.pop();
        if(value==getMin()){
            stackMin.pop();
        }
        return value;
    }
    //--------------------------


    //方案2
    //比方案1多费空间,但省时间
    public void push2(int newNum){
        if(stackMin.isEmpty()){
            stackMin.push(newNum);
        }else if(getMin()<newNum){
            stackMin.push(stackMin.peek());
        }else{
            stackMin.push(newNum);
        }
        stackData.push(newNum);
    }

    public int pop2(){
        if(stackData.isEmpty()){
            throw new RuntimeException("stack is null");
        }
        stackMin.pop();
        return stackData.pop();
    }

}

2,由两个栈组成的队列

编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)
public class TwoStackQueue{
    private Stack<Integer> stackPush; 
    private Stack<Integer> stackPop;

    public TwoStackQueue(){
        stackPush=new Stack<>();
        stackPop=new Stack<>();
    }

    public void add(int newNum){
        stakPush.push(newNum);
    }

    public int poll(){
        if(stackPush.isEmpty() && stackPop.isEmpty()){
            throw new RuntimeException("stack is null");        
        }else if(stackPop.isEmpty()){
            while(!stackPush.isEmpty()){
                stackPop.push(stackPush.pop());
            }   
        }
        return stackPop.pop();
    }
    
    publuc int peek(){
        if(stackPush.isempty() && stackPop.isEmpty()){
            throw new RuntimeException("stack is null");
        }else if(stackPop.isEmpty()){
            while(!stackPush.isEmpty()){
                stackPop.push(stackPush.pop());
            }
        }
        retuen stackPop.peek();
    }
}

3,如何仅用递归函数和栈操作逆序一个栈

题目:
一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。将这个栈转置后,从栈顶到栈底为1、2、3、4、5,也就是实现栈中元素的逆序,但是只能用递归来实现。
public static int getAndRemoveLast(Stack<Integer> stack){
     int result =stack.pop();
     //System.out.println("result:"+result);
     if(stack.isEmpty()){
         return result;
     }else{
         int last =getAndRemoveLast(stack);
         //System.out.println("last:"+last);
         stack.push(result);
         return last;
    }
}

public static void reverse(Stack<Integer> stack){
     if(stack.isEmpty()){
         return;
     }
     int i=getAndRemoveLast(stack);
     //System.out.println("i:"+i);
     reverse(stack);
     //System.out.println("push i="+i);
     stack.push(i);
}

测试:

public static void main(String args[]){
     Stack<Integer> stack =new Stack<>();
     stack.push(1);
     stack.push(2);
     stack.push(3);
     stack.push(4);
     stack.push(5);
     System.out.println(stack.toString());
     reverse(stack);
     System.out.println(stack.toString());
}

输出:

[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

4,用一个栈实现另一个栈的排序

    public static void sortStack(Stack<Integer> stack) {
        if (stack.isEmpty()) {
            throw new RuntimeException("stack is null");
        }
        Stack<Integer> help = new Stack<>();
        while (!stack.isEmpty()) {
            int value = stack.pop();
            while (!help.isEmpty() && value < help.peek()) {
                stack.push(help.pop());
            }
            help.push(value);
        }
        while (!help.isEmpty()) {
            stack.push(help.pop());
        }
    }

测试:

    public static void main(String[] args){
        Stack<Integer> stack=new Stack<>();
        stack.push(5);
        stack.push(3);
        stack.push(5);
        stack.push(2);
        stack.push(1);
        stack.push(7);
        stack.push(8);
        stack.push(7);
        System.out.println(stack.toString());
        sortStack(stack);
        System.out.println(stack.toString());
    }

输出:

[5, 3, 5, 2, 1, 7, 8, 7]
[8, 7, 7, 5, 5, 3, 2, 1]

5.1,递归实现汉诺塔问题

public static int hanoiProblem(int num,String left,String mid,String right){
        if(num<1){
            return 0;
        }
        return process(num,left,mid,right,left,right);
    }

    public static int process(int num,String left,String mid,String right,String from,String to){
        if(num==1){
            if(from.equals(mid) || to.equals(mid)){
                System.out.println("Move 1 from "+from +" to "+to);
                return 1;
            }else{
                System.out.println("Move 1 form "+ from +" to "+mid);
                System.out.println("Move 1 form "+ mid +" to "+to);
                return 2;
            }
        }
        if(from.equals(mid) || to.equals(mid)){
            String another=(from.equals(left) || to.equals(left) ? right:left);
            int part1=process(num-1,left,mid,right,from,another);
            int part2=1;
            System.out.println("Move "+num+ " from "+from+" to "+to);
            int part3=process(num-1,left,mid,right,another,to);
            return part1+part2+part3;
        }else{
            int part1=process(num-1,left,mid,right,from,to);
            int part2=1;
            System.out.println("Move "+num+" from "+from+" to "+mid);
            int part3=process(num-1,left,mid,right,to,from);
            int part4=1;
            System.out.println("Move "+ num+" form "+mid+" to "+to);
            int part5=process(num-1,left,mid,right,from,to);
            return part1+part2+part3+part4+part5;
        }
    }

5.2,通过栈实现汉诺塔

    public enum Action{
        No,LToM,MToL,MToR,RToM
    }
    
    public static int hanoiProblem2(int num,String left,String mid,String right){
        Stack<Integer> lS=new Stack<>();
        Stack<Integer> mS=new Stack<>();
        Stack<Integer> rS=new Stack<>();

        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);
        }

        Action[] record ={Action.No};

        int step=0;
        while (rS.size()!=num+1){
            step += fStackToStack(record, Action.MToL,Action.LToM,lS,mS,left,mid);
            step += fStackToStack(record, Action.LToM,Action.MToL,mS,lS,mid,left);
            step += fStackToStack(record, Action.RToM,Action.MToR,mS,rS,mid,right);
            step += fStackToStack(record, Action.MToR,Action.RToM,lS,mS,right,mid);
        }
        return step;
    }

    public  static int fStackToStack(Action[] record,Action preNoAct,Action nowAct,Stack<Integer> fStack,Stack<Integer> tStack,String from,String to){
        if(record[0] !=preNoAct && fStack.peek()<fStack.peek()){
            tStack.push(fStack.pop());
            System.out.println("Move "+tStack.peek()+" from "+from+" to "+to);
            record[0]=nowAct;
            return 1;
        }
        return 0;
    }