代码随想录刷题|LeetCode 栈和队列的理论基础 232.用栈实现队列 225. 用队列实现栈

目录

栈和队列的理论基础

232.用栈实现队列

思路

用栈实现队列

225.用队列实现栈

思路

用队列实现栈

用两个队列实现栈

用一个队列实现栈


栈和队列的理论基础

  • 栈(stack):
    • 特点:先进后出(LIFO)
    • java底层:
      • Java中的Stack<E>类继承了Vector<E>类
      • 一般使用Deque<E>实现stack【Deque<Integer> stack = new ArrayDeque<Integer>();
    • 基本操作:
      • push() ---- 进栈
      • pop() ---- 出栈
      • peek() ---- 查看栈顶元素
      • empty() ---- 测试栈是否为空
    • 实现:
      • 使用链表实现栈
      • 使用数组实现栈
      • 使用队列实现栈
  • 队列(queue):
    • 特点:后进后出(FIFO)
    • Queue<E>的java底层:
      • Java中Queue<E>接口继承了Collection<E>接口
      • 一般用LinkedList<E>类进行实现
    • Queue基本操作:
      • add()、offer()  ---- 从队尾添加元素
      • remove()、poll() ---- 从队头删除元素
      • element()、peek() ---- 查看队头元素 
    • Deque<E>的java底层:
      • Java中Deque<E>接口继承了Queue<E>接口
      • 支持在两端插入和移除元素
      • deque <----> double ended queue 双端队列
      • Deque<E>可以等效Queue<E>
      • Deque<E>可以等效Stack<E>,优先使用此接口
    • Deque基本操作:
      • addFirst()、offerFirst() ---- 在队头添加元素
      • removeFirst()、pollFirst() ---- 从队头删除元素
      • getFirst()、peekFirst() ---- 查看队头元素 
      • addLast()、offerLast() ---- 在队尾添加元素
      • removeLast()、pollLast() ---- 从队尾删除元素
      • getLast()、peekLast() ---- 查看队尾元素 
    • 实现:
      • 使用链表实现队列
      • 使用数组实现队列
      • 使用栈实现队列

232.用栈实现队列

题目链接:力扣

思路

        首先使用一个栈来模拟队列,入队相当于入栈,但是出队的话队头还压在栈底,要出来的话就需要将此栈中的元素全部弹出。
        此时可以用另一个栈来保存弹出的元素,那么上一个栈中的栈底元素就在这个栈的栈顶元素,就是队列的队头,如果需要出队和查看队头就都可以进行操作了
 

用栈实现队列

        第一步:定义一个入栈和一个出栈
        第二步:实现push() --- 最好实现
        第三步:实现pop() --- 出栈为出队
                首先需要判断出栈是不是为空
                        如果出栈为空,要将入栈中的所有元素加入到出栈中,再从出栈中进行出队
                        如果不为空,说明出栈中还有元素,元素从出栈中进行出队
        第四步:实现peek()
                首先需要判断出栈是否为空
                        如果出栈为空,要将入栈中的所有元素加入到出栈中,再从出栈中返回队头
                        如果不为空,说明出栈中还有元素,从出栈中返回队头
        第五步:实现isEmpty()
                只有出栈和入栈中所有的元素为空,才算整个队列为空                      

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.isEmpty()) {
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.pop();
    }
    
    public int peek() {
        if (stackOut.isEmpty()) {
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        } else {}
        return stackOut.peek();
    }
    
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }
}

225.用队列实现栈

题目链接:力扣

思路

        因为有了上道题的经验,首先的思维就是用两个队列对栈进行实现,按照上道题目的思路是不可以的,因为把一个队列移动到另一个队列,出队的顺序并没有发生变化。所以需要转换思路。如果每次添加的数字都不出现在队尾,而是出现在队头就可以了。
        那就每次添加数字的时候,先进q2,然后把q1已有的元素添加到q2,此时q2就是栈的顺序了,q1就为空了。但是我们得固定一个队列进行出栈操作,所以就把q1和q2进行交换。此时q1就是一个栈了,q2就为空,这样就实现了栈

         那么如何用一个队列实现栈呢,压栈可以是入队,但是弹栈的时候需要队尾元素出来,怎么办呢,那就可以跟进队列的长度,把除队尾元素的元素全部出队再入队,这样队尾元素就到队头了,可以进行pop

        那么top怎么实现呢,因为只查不删,所以直接返回队尾元素就可以了,java的Queue接口没有直接返回队尾元素的功能,所以我们要么使用Deque接口,要么就需要在添加元素的时候下功夫了,这样的队列才可以top和pop
        随意每添加一个元素,就给队列中的元素重新排个序,保持队列中一直是压栈的顺序 

         如果使用Deque接口的话,就直接在每次删除的时候变换顺序就可以了,查询的话查询队尾就可以 

用队列实现栈

用两个队列实现栈

        第一步:创建两个队列
        第二步:实现push() --- 压栈
                先进q2进行待命
                让q1中的元素进q2,实现了新进的元素都在队头(栈顶)
                让q1和q2进行交换
        第三步:实现pop()
                q1进行出队
        第四步:实现peek()
                q1进行考察队头
        第五步:实现empty()
                q1是否为空

class MyStack {

    Queue<Integer> queue1; 
    Queue<Integer> queue2; 

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();  
    }
    
    // 向栈中添加元素,这里queue2就是个备份队列
    // 经过一番操作,queue1其实就是栈的顺序
    public void push(int x) {
        queue2.offer(x);
        while (!queue1.isEmpty()) {
            queue2.offer(queue1.poll());
        }
        // 到此处,queue2就有栈的顺序了,queue为空队列,已经被搬空了
        // 然后再对queue1和queue2进行交换
        Queue<Integer> queueTemp;
        queueTemp = queue1;
        queue1 = queue2;
        queue2 = queueTemp;
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue2.isEmpty();
    }
}

用一个队列实现栈

        第一步:创建队列
        第二步:实现push()
                为了让top和pop更加方便,避免这两个操作临近操作时出错,在添加的时候就将顺序排成栈的顺序
                每入队一个元素,就将前面的元素出队再入队,这样保证了队头是栈顶元素
        第三步:实现pop()
                排好队的队列出队
        第四步:实现top()
                排好队的队列查队头
        第五步:实现empty()
                队列是否为空

class MyStack {

    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<>();
    }
    
    public void push(int x) {
        queue.offer(x);
        int len = queue.size() - 1;
        while (len-- > 0) {
            queue.offer(queue.poll());
        }
        
    }
    
    public int pop() {  
        return queue.poll();
    }
    
    public int top() {
        return queue.peek();
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值