代码随想录算法训练营第十天|栈与队列基础+队列模拟栈+栈模拟队列

文章目录

    • 栈与队列基础
      • Stack 类的常用方法:
    • 232.用栈实现队列
      • 思路
      • 代码
    • 225. 用队列实现栈
      • 思路1:2个队列模拟栈
      • 思路2:一个队列,每次pop时更改位置由123变为312
      • 思路3:一个队列,每次push时更改位置由123变为312

栈与队列基础

代码随想录算法训练营第十天|栈与队列基础+队列模拟栈+栈模拟队列_第1张图片

Stack 类的常用方法:

  • push(E item):

    将元素压入栈顶。

  • pop():
    弹出栈顶元素。

  • peek():

    查看栈顶元素,但不移除。

  • empty():

    判断栈是否为空。

  • search(Object o):

    在栈中查找元素并返回相对于栈顶的位置,如果找不到返回 -1。

232.用栈实现队列

代码随想录算法训练营第十天|栈与队列基础+队列模拟栈+栈模拟队列_第2张图片

思路

这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。

使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。

下面动画模拟以下队列的执行过程:

执行语句:
queue.push(1);
queue.push(2);
queue.pop(); 注意此时的输出栈的操作
queue.push(3);
queue.push(4);
queue.pop();
queue.pop();注意此时的输出栈的操作
queue.pop();
queue.empty();

代码

  1. 自己写的
class MyQueue {
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;
    public MyQueue() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        if(stackOut.empty()){
            while(!stackIn.empty()){
                stackOut.push(stackIn.pop());
            }
            return stackOut.pop();
        }else{
            return stackOut.pop();
        }
        
    }
    
    public int peek() {
        if(stackOut.empty()){
            while(!stackIn.empty()){
                stackOut.push(stackIn.pop());
            }
            return stackOut.peek();
        }else{
            return stackOut.peek();
        }
    }
    
    public boolean empty() {
        return stackIn.empty()&&stackOut.empty();
    }
}

2.代码随想录代码复用
如果stackout不为空,直接对stackout进行peek或pop操作即可模拟队列的先入先出。
如果stackout为空,则把stackin的全部放入stackout再对stackout进行操作。

class MyQueue {

    Stack<Integer> stackIn;
    Stack<Integer> stackOut;

    /** Initialize your data structure here. */
    public MyQueue() {
        stackIn = new Stack<>(); // 负责进栈
        stackOut = new Stack<>(); // 负责出栈
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        stackIn.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {    
        dumpstackIn();
        return stackOut.pop();
    }
    
    /** Get the front element. */
    public int peek() {
        dumpstackIn();
        return stackOut.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }

    // 如果stackOut为空,那么将stackIn中的元素全部放到stackOut中
    private void dumpstackIn(){
        if (!stackOut.isEmpty()) return; 
        while (!stackIn.isEmpty()){
                stackOut.push(stackIn.pop());
        }
    }
}

225. 用队列实现栈

代码随想录算法训练营第十天|栈与队列基础+队列模拟栈+栈模拟队列_第3张图片

思路1:2个队列模拟栈

队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。

所以用栈实现队列, 和用队列实现栈的思路还是不一样的,这取决于这两个数据结构的性质。

但是依然还是要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!

如下面动画所示,用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。

queue.push(1);        
queue.push(2);        
queue.pop();   // 注意弹出的操作       
queue.push(3);        
queue.push(4);       
queue.pop();  // 注意弹出的操作    
queue.pop();    
queue.pop();    
queue.empty();    

思路2:一个队列,每次pop时更改位置由123变为312

一个队列
每次需要栈顶元素时,将后面的元素转移到前面。

class MyStack {
    Queue<Integer> q;
    public MyStack() {
        q=new LinkedList<>();
    }
    
    public void push(int x) {
        q.add(x);
    }
    
    public int pop() {
        rePosition();
        return q.poll();
    }
    
    public int top() {
        rePosition();//改变元素位置后还需要复原位置
        // return q.peek();
        int result=q.poll();
        q.add(result);
        return result;
    }
    
    public boolean empty() {
        return q.isEmpty();
    }
    public void rePosition(){
        int size = q.size()-1;
        // size--;
        // while(size-->0)
        //     q.add(q.poll());
        //等价于
        while(size>0){
            q.add(q.poll());
            size--;
        }
    }
}

思路3:一个队列,每次push时更改位置由123变为312

class MyStack {
    Queue<Integer> queue;

    /** Initialize your data structure here. */
    public MyStack() {
        queue = new LinkedList<Integer>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        int n = queue.size();
        queue.offer(x);
        for (int i = 0; i < n; i++) {
            queue.offer(queue.poll());
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue.poll();
    }
    
    /** Get the top element. */
    public int top() {
        return queue.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue.isEmpty();
    }
}

你可能感兴趣的:(算法,java,开发语言)