代码随想录算法训练营第十天 | 理论基础 232.用栈实现队列 225. 用队列实现栈

今日任务:

理论基础

232.用栈实现队列

225. 用队列实现栈

理论基础

了解一下 栈与队列的内部实现机智,文中是以C++为例讲解的。

文章讲解:https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

232.用栈实现队列

大家可以先看视频,了解一下模拟的过程,然后写代码会轻松很多。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html

思路:需要两个栈一个输入栈,一个输出栈

 

在push数据的时候,只要数据放进输入栈就好,但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入),再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。

最后如何判断队列为空呢?如果进栈和出栈都为空的话,说明模拟的队列为空了。

class MyQueue {
    //输入栈s1、输出栈s2
    Stack<Integer> s1;
    Stack<Integer> s2;
    public MyQueue() {
        s1 = new Stack<>();//负责进队
        s2 = new Stack<>();//负责出队
    }
    
    public void push(int x) {
        s1.push(x);
    }
    
    public int pop() {
        dumpstackIn();
        return s2.pop();
    }
    
    public int peek() {
        dumpstackIn();
        return s2.peek();
    }
    
    public boolean empty() {
        return s1.isEmpty() && s2.isEmpty();
    }
    private void dumpstackIn(){
        if (!s2.isEmpty()) return;
        while (!s1.isEmpty()){
            s2.push(s1.pop());
        }
    }
}

225. 用队列实现栈

题目链接/文章讲解/视频讲解:https://programmercarl.com/0225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.html

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

 

使用两个queue:

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;

    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    public void push(int x) {
        queue2.offer(x);
        while (!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        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 queue1.isEmpty();
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:39.4 MB,击败了35.41% 的Java用户

使用两个Deque:

class MyStack {
    // Deque 接口继承了 Queue 接口
    // 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> que1;// 和栈中保持一样元素的队列
    Deque<Integer> que2;// 辅助队列

    public MyStack() {
        que1 = new ArrayDeque<>();
        que2 = new ArrayDeque<>();
    }

    public void push(int x) {
        que1.addLast(x);
    }

    public int pop() {
        int size = que1.size();
        size--;
        // 将 que1 导入 que2 ,但留下最后一个值
        while (size-- > 0){
            que2.addLast(que1.peekFirst());
            que1.pollFirst();
        }
        int res = que1.pollFirst();
        // 将 que2 对象的引用赋给了 que1 ,此时 que1,que2 指向同一个队列
        que1 = que2;
        // 如果直接操作 que2,que1 也会受到影响,所以为 que2 分配一个新的空间
        que2 = new ArrayDeque<>();
        return res;
    }

    public int top() {
        return que1.peekLast();
    }

    public boolean empty() {
        return que1.isEmpty();
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:39.3 MB,击败了44.49% 的Java用户

优化,使用一个 Deque 实现

class MyStack {
    Deque<Integer> que1;

    public MyStack() {
        que1 = new ArrayDeque<>();
    }

    public void push(int x) {
        que1.addLast(x);
    }

    public int pop() {
        int size = que1.size();
        size--;
        // 将 que1 导入 que2 ,但留下最后一个值
        while (size-- > 0){
            que1.addLast(que1.peekFirst());
            que1.pollFirst();
        }
        int res = que1.pollFirst();
        return res;
    }

    public int top() {
        return que1.peekLast();
    }

    public boolean empty() {
        return que1.isEmpty();
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:39.3 MB,击败了43.09% 的Java用户

优化,使用一个 Queue 实现:

class MyStack {
    Queue<Integer> queue;
    public MyStack() {
        queue = new LinkedList<>();
    }
    //每 offer 一个数(A)进来,都重新排列,把这个数(A)放到队列的队首
    public void push(int x) {
        queue.offer(x);
        int size = queue.size();
        //移动除了 A 的其它数
        while (size-- > 1){
            queue.offer(queue.poll());
        }
    }

    public int pop() {
        return queue.poll();
    }

    public int top() {
        return queue.peek();
    }

    public boolean empty() {
        return queue.isEmpty();
    }
}
info
			解答成功:
			执行耗时:0 ms,击败了100.00% 的Java用户
			内存消耗:39.1 MB,击败了83.90% 的Java用户
posted @ 2022-11-29 11:22  染醉霜林  阅读(39)  评论(0)    收藏  举报