栈和队列相关数据结构的设计问题

题目一:设计一个带有getMin功能的栈

[leetcode155]https://leetcode.com/problems/min-stack/

解法一:两个栈,其中help栈压入的都是最小值,同步压入,同步弹出,最省时间

public class MinStack {
    Stack data;
    Stack help;
    /** initialize your data structure here. */
    public MinStack() {
        data=new Stack();
        help=new Stack();
    }
    
    public void push(int x) {
        if(data.isEmpty()){
            data.push(x);
            help.push(x);
        }else{
            data.push(x);
            help.push(Math.min(help.peek(),x));
        }    
    }
    
    public void pop() {
        if(data.isEmpty())
            throw new RuntimeException("your stack is rmpty");
        data.pop();
        help.pop();
    }
    
    public int top() {
        if(data.isEmpty())
            throw new RuntimeException("your stack is rmpty");
        return data.peek();
    }
    
    public int getMin() {
        return help.peek();
    }
}

解法二:两个栈,压入时当前数小于等于栈顶元素才压入,弹出时当前栈顶大于help栈顶才弹出,省了一些空间

public class MinStack {
    Stack data;
    Stack help;
    /** initialize your data structure here. */
    public MinStack() {
        data=new Stack();
        help=new Stack();
    }
    
    public void push(int x) {
        if(data.isEmpty()){
            data.push(x);
            help.push(x);
        }else{
            data.push(x);
            if(x<=help.peek())
                help.push(x);
        }    
    }
    
    public void pop() {
        // if(data.isEmpty())
        //     throw new RuntimeException("your stack is rmpty");
        int cur=data.peek();
        data.pop();
        if(cur==help.peek())
            help.pop();
    }
    
    public int top() {
        // if(data.isEmpty())
        //     throw new RuntimeException("your stack is rmpty");
        return data.peek();
        
    }
    
    public int getMin() {
        return help.peek();
    }
}

方法三:只使用一个栈,另外使用一个变量来记录最小,栈中压入的是与最小值的差。

public class MinStack {
    private long min;
    Stack stack;

    /** initialize your data structure here. */
    public MinStack() {
        stack=new Stack();
    }
    
    public void push(int x) {
        if(stack.isEmpty()){
            min=x;
            stack.push(0L);//为了和后面统一起来
        }
        else{
            stack.push(x-min);
            if(x0)
            return (int)(min+peek);
        else
            return (int)min;
        
    }
    
    public int getMin() {
        return (int)min;
    }
}

题目二 两个栈实现队列

两个栈data help,只要注意两点
1. help为空的时候才能往里面导数。

  1. 导数就要把data中的所有数都导完。
class MyQueue {
   Stack data=new Stack();
   Stack help=new Stack();
   // Push element x to the back of queue.
   public void push(int x) {
       data.push(x);
   }

   // Removes the element from in front of queue.
   public void pop() {
       if(help.isEmpty()&&data.isEmpty())
           throw new RuntimeException("your queue is empty");
       else if(help.isEmpty()){
           while(!data.isEmpty())
               help.push(data.pop());
       }
       help.pop();
   }

   // Get the front element.
   public int peek() {
       if(help.isEmpty()&&data.isEmpty())
           throw new RuntimeException("your stack is empty");
       else if(help.isEmpty()){
           while(!data.isEmpty())
               help.push(data.pop());
       }
       return help.peek();
   }

   // Return whether the queue is empty.
   public boolean empty() {
       return help.isEmpty()&&data.isEmpty();
   }
}

题目三 两个队列实现栈

class MyStack {
   Queue data=new LinkedList();
   Queue help=new LinkedList();
   // Push element x onto stack.
   public void push(int x) {
       data.add(x);
   }

   // Removes the element on top of the stack.
   public void pop() {
       if(data.isEmpty())
           throw new RuntimeException("your stack is empty!");
       while(data.size()!=1){
           help.add(data.poll());
       }
       data.poll();
       while(!help.isEmpty()){
           data.add(help.poll());
       }
   }

   // Get the top element.
   public int top() {
       if(data.isEmpty())
           throw new RuntimeException("your stack is empty!");
       while(data.size()!=1){
           help.add(data.poll());
       }
       int tmp=data.peek();
       help.add(data.poll());//小心这里
       while(!help.isEmpty()){
           data.add(help.poll());
       }
       return tmp;
   }

   // Return whether the stack is empty.
   public boolean empty() {
       return data.isEmpty();
   }
}

题目四 仅使用递归实现栈的逆序

有利于对于递归的理解
要求只使用递归实现一个栈的逆序

思路:

假如不限条件,要实现一个栈的逆序,那么我们直接借助一个栈就可以实现了,这里不能再显试的使用栈,那么我们就使用递归来利用系统的递归栈来实现。
这里首先思考getAndRemoveLast这个递归函数,用于得到一个栈的栈底元素,并且删除设个栈底元素。然后现在我们在每次递归返回的时候把之前保留的元素加到栈中,就可以实现逆序。

public static void reverse(Stack stack){
    if(stack.isEmpty())
        return;
    int i=getAndRemoveLast(stack);
    reverse(stack);
    stack.push(i);
}
public static int getAndRemoveLast(Stack stack){
    int res=stack.pop();
    if(stack.isEmpty()){
        return res;
    }
    else{
        int last=getAndRemoveLast(stack);
        stack.push(res);
    
        return last;
    }
}

你可能感兴趣的:(栈和队列相关数据结构的设计问题)