代码随想录day10| 232.用栈实现队列、4225. 用队列实现栈

目录

栈与队列理论基础

232  用栈实现队列

4225  用队列实现栈


栈与队列理论基础

栈与队列:栈为先进后出,队列为先进先出的结构。

Queue以及Deque平常在写leetcode经常用LinkedList向上转型Deque作为栈或者队列使用。

 

private static void usingAsQueue() {
        Deque<Integer> queue=new ArrayDeque<>();
 
        System.out.println("队列为空:"+queue.isEmpty());   //判断队列是否为空
 
        queue.addLast(12);   //添加元素
        System.out.println(queue.peekFirst());   //获取队列首部元素
        System.out.println(queue.pollFirst());   //获取并移除栈顶元素
 
 }
 
private static void usingAsStack() {
        //作为栈使用
        Deque<Integer> stack=new LinkedList<>();
 
        System.out.println("栈为空:"+stack.isEmpty());   //判断栈是否为空
 
        stack.addFirst(12);//添加元素
        System.out.println(stack.peekFirst());   //获取栈顶元素
        System.out.println(stack.pollFirst());   //获取并移除栈顶元素
    }

232  用栈实现队列

题目链接

看到题目的第一想法:对栈与队列了解较少,看到后完全是没有思路的状态。

看完代码随想录之后的想法:按部就班的处理即可,先是定义两个栈,入栈stackIn与出栈stackOut,而后对队列进行初始化操作;

  • 向队列中添加元素,只需要向入栈中push即可
  • 队列弹出元素较为复杂,因为队列是先进先出的数据结构,而栈是先进后出的,故弹出时,先判断stackOut是否是空的:如果是空的,而若此时stackIn不为空,就将入栈的所有元素,依次弹出并放入出栈中。而后直接在出栈中弹出元素即可,这就用两个栈实现了队列的pop功能。
  • 获取队列的顶部元素:直接复用pop方法即可,唯一不同是,peek不需要弹出,因此在调用this.pop()之后,再将此元素放入stackOut即可;
  • 队列是否为空:两个栈有一个不为空时队列不为空,否则为空。判断队列是否为空的方法为:stack.isEmpty().

代码实现:

class MyQueue {
    //stack的初始化与定义??如何处理
    //定义一个入栈和一个出栈
    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() {
        //如果stackout为空,就将stackin中的所有元素放入stackout中
        //若不为空,直接弹出元素
        //isEmpty()方法
        if (stackOut.isEmpty()) {
            while (!stackIn.isEmpty()) {
                stackOut.push(stackIn.pop());
            }
        }
        return stackOut.pop();
    }
    
    public int peek() {
        //复用pop方法
        //int result = stackOut.pop();
        int result = this.pop();
        stackOut.push(result);
        return result;
    }
    
    public boolean empty() {
        //至少一个不为空时,队列不为空
        if (!stackIn.isEmpty() || !stackOut.isEmpty()){
            return false;
        }
        return true;
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

实现过程中遇到哪些困难:

  • 不会定义栈,不会初始化队列,不了解栈的push,pop,peek,isEmpty等方法!
  • this可以调用当前类的其他方法等

4225  用队列实现栈

题目链接

 看到题目的第一想法:没有思路,不清楚如何用队列实现栈

看完代码随想录之后的想法:卡哥提供的代码时使用队列deque,而后对栈初始化:

  • 添加元素使用的是addLast方法;
  • 栈的弹出元素操作:获取队列的长度,而后队列减一,即将队列中前size-1个元素全部在加到队列的后方。在完成之后移除队列的第一个元素即可,即实现了栈的pop功能
  • 获取栈顶元素,arrayDeque.getLast()获取队列最后一个元素即相当于栈顶元素;
  • 判断栈是否为空,直接判断队列是否为空即可,arrayDeque.isEmpty()

代码实现:(使用一个deque实现)

class MyStack {
    //使用一个队列即可实现栈
    //deque双端队列(两侧都可以增删元素),queue单端队列(先进先出)
    Deque<Integer> que;
    public MyStack() {
        que = new ArrayDeque<>();
    }
    
    public void push(int x) {
        que.addLast(x);
    }
    
    public int pop() {
        int size = que.size();
        size--;
        //下面应为 > 0而非 >= 0
        while (size-- > 0) {
            que.addLast(que.peekFirst());
            que.pollFirst();
        }
        int res = que.pollFirst();
        return res;
    }
    
    public int top() {
        //java中队列有back吗?
        return que.getLast();
    }
    
    public boolean empty() {
        return que.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

使用一个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();
    }
}

使用两个queue实现:

class MyStack {

    Queue<Integer> queue1; // 和栈中保持一样元素的队列,此处保持一致即出栈顺序一致
    Queue<Integer> queue2; // 辅助队列

    /** Initialize your data structure here. */
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        queue2.offer(x); // 先放在辅助队列中
        while (!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        Queue<Integer> queueTemp;
        queueTemp = queue1;
        queue1 = queue2;
        queue2 = queueTemp; // 最后交换queue1和queue2,将元素都放到queue1中
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue1.poll(); // 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
    }
    
    /** Get the top element. */
    public int top() {
        return queue1.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue1.isEmpty();
    }
}

用两个deque实现栈:

class MyStack {
    // Deque 接口继承了 Queue 接口
    // 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
    Deque<Integer> que1; // 和栈中保持一样元素的队列,此处保持一致为入栈顺序一致
    Deque<Integer> que2; // 辅助队列
    /** Initialize your data structure here. */
    public MyStack() {
        que1 = new ArrayDeque<>();
        que2 = new ArrayDeque<>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        que1.addLast(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    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;
    }
    
    /** Get the top element. */
    public int top() {
        return que1.peekLast();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return que1.isEmpty();
    }
}

实现过程中遇到哪些困难:

  • 队列的相关方法不了解,需要多熟悉,比如ArrayDeque的addLast,peekFirst,pollFirst,getLast,isEmpty等

今日收获,记录一下自己的学习时长

  • 算法处理约3h,博客编写约1.5h
  • 熟悉了队列与栈相互实现的操作,与其基本用法,还要多加了解~
  • 贵在坚持,加油!

引用:Queue与Deque的区别_Morning sunshine的博客-CSDN博客_queue deque

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值