【算法第八天7.21】用队列实现栈,用栈实现队列

链接力扣225-用队列实现栈

思路

队列实现栈可以只用一个队列Deque,这个队列非常好用

Deque 接口继承了 Queue 接口
Queue 中的 add、poll、peek等效于 Deque 中的
addLast、pollFirst、peekFirst
addFirst、pollLast、peekLast 这些也可以使用

  Deque<Integer> deque = new ArrayDeque<>();

push可以调用队列中的addLast

empty直接判断队列是否为空即可

top直接返回队列的peekLast(因为在栈中最后进的为栈顶)

逻辑主要在pop:
deque主要是让要出栈(出队)的元素跑到队头的位置,但它又是最后进队的,此时可以让其它元素依次放到这个元素的后面addLast(),先使用peekFirst()放入队的末位,再让其出队pollFirst()

// 优化,使用一个 Deque 实现
class MyStack {
    // Deque 接口继承了 Queue 接口
    // Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> deque;
    public MyStack(){
        deque = new ArrayDeque<>();
    }
    public void push(int x){
        deque.addLast(x);
    }
    public int pop(){
        int len = deque.size();
        // 最后要留一个元素不住
        len--;
        while(len > 0){
            //把要出栈的元素一直推到第一个,把其它元素,循环放到最后,最后得到的结果,就是按出栈顺序出来的
            deque.addLast(deque.peekFirst());
            deque.pollFirst();
            len--;
        }
        int res = deque.pollFirst();
        return res;
    }
    public int top() {
        return deque.peekLast();
    }

    public boolean empty() {
        return deque.isEmpty();
    }
}

链接力扣232-用栈实现队列

思路

栈实现队列需要两个栈:进栈和出栈

重点:如果要开始将进栈中的元素放入出栈,需要一次性放完,不能有剩余
之后再向出栈中放元素时,需要清空出栈

push:直接使用栈的push

pop:弹出队头元素(两个考虑:出栈为空和出栈不为空),返回出栈的栈顶

出栈为空:需要将进栈中的元素(进栈清空),全部弹到出栈中
出栈不为空:直接pop出栈的栈顶元素

empty:入栈出栈都为空,则队列为空

peek:返回出栈的栈顶元素(两个考虑:出栈为空和出栈不为空),需要将进栈中的元素全都放到出栈中,才能得到队头元素

出栈为空:需要将进栈中的元素(进栈清空),全部弹到出栈中
出栈不为空:直接pop出栈的栈顶元素

提取共同操作:出栈为空和出栈不为空
步骤
1、如果出栈不为空,则return,直接进行pop或者peek
2、出栈为空,而进栈不为空,则循环(while)将其中元素放入出栈中,将进栈中的元素(进栈清空),全部弹到出栈中

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() {
        // 开始进行弹出操作时,需要先清空进栈
        // 弹出队头元素,需要将进栈中的元素,全部弹到出栈中
        dumpstackIn();
        return stackOut.pop();
    }
    
    public int peek() {
        // 获取队头元素,需要先清空进栈
        // 获得队头元素,需要将进栈中的元素,全部弹到出栈中
        dumpstackIn();
        return stackOut.peek();
    }
    
    public boolean empty() {
        
        return stackOut.isEmpty() && stackIn.isEmpty();

    }
    // 清空进栈
    private void dumpstackIn(){
        // 如果出栈非空,则在调用此函数时,直接进行下一步:peek或者pop即可
        if(!stackOut.isEmpty()) return;
        // 如果出栈为空,则需要将进栈中的元素全部放入出栈中
        // 如果进栈不为空,则一直将栈顶元素弹出,直到进栈排空,再进行出栈的操作
        while(!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
        }
    }
}

你可能感兴趣的:(算法,数据结构,java)