【LeetCode+JavaGuide打卡】Day10|232. 用栈实现队列、225. 用队列实现栈

学习目标:

  • 232. 用栈实现队列
  • 225. 用队列实现栈
  • Java集合常见面试题总结(上)

学习内容:

来源:JavaGuide
【LeetCode+JavaGuide打卡】Day10|232. 用栈实现队列、225. 用队列实现栈_第1张图片

  • Queue 是单端队列,只能从一端插入元素,另一端删除元素,实现上一般遵循 先进先出(FIFO) 规则。
    【LeetCode+JavaGuide打卡】Day10|232. 用栈实现队列、225. 用队列实现栈_第2张图片

  • Deque 是双端队列,在队列的两端均可以插入或删除元素。

  • Deque 还提供有 push() 和 pop() 等其他方法,可用于模拟栈【LeetCode+JavaGuide打卡】Day10|232. 用栈实现队列、225. 用队列实现栈_第3张图片

  • ArrayDeque 和 LinkedList 都实现了 Deque 接口,两者都具有队列的功能

  • ArrayDeque 是基于可变长的数组和双指针来实现,而 LinkedList 则通过链表来实现

  • ArrayDeque 不支持存储 NULL 数据,但 LinkedList 支持。

  • ArrayDeque 是在 JDK1.6 才被引入的,而LinkedList 早在 JDK1.2 时就已经存在。

  • ArrayDeque 插入时可能存在扩容过程, 不过均摊后的插入操作依然为 O(1)。

  • 虽然 LinkedList 不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。

  • 从性能的角度上,选用 ArrayDeque 来实现队列要比 LinkedList 更好。此外,ArrayDeque 也可以用于实现栈


232. 用栈实现队列

题目链接 &&文章讲解
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

//分别定义输入栈和输出栈
//push:数据放进输入栈就好
//pop:输出栈如果为空,就把进栈数据全部导入进来,再从出栈弹出数据
//     如果输出栈不为空,则直接从出栈弹出数据
class MyQueue {
    Deque<Integer> stackIn;
    Deque<Integer> stackOut;
    public MyQueue() {
        stackIn=new LinkedList<>();
        stackOut=new LinkedList<>();
    }
    
    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() {
        int res=this.pop();
        stackOut.push(res);
        return res;
    }
    
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }
}

225. 用队列实现栈

题目链接&&文章讲解
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

//分别定义输入队列和输出队列:队列是先进先出的规则,把一个队列中的数据导入另一个队列中,数据的顺序并没有变,并没有变成先进后出的顺序。

//方法一:用两个队列que1和que2实现队列的功能,que2进行备份
class MyStack {
    Queue<Integer> que1;
    Queue<Integer> que2;
    public MyStack() {
        que1 = new LinkedList<>();
        que2 = new LinkedList<>();
    }
    //在加入元素时先将q1中的元素依次出栈压入q2,
    //然后将新加入的元素压入q1,再将q2中的元素依次出栈压入q1
    public void push(int x) {
        while(!que1.isEmpty()){
            que2.offer(que1.poll());
        }
        que1.offer(x);
        while(!que2.isEmpty()){
            que1.offer(que2.poll());
        }
    }
    
    public int pop() {
        return que1.poll();
    }
    
    public int top() {
        return que1.peek();
    }
    
    public boolean empty() {
        return que1.isEmpty();
    }
}


//方法二:用一个队列
//一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了
class MyStack {
    Queue<Integer> queue;
    public MyStack() {
        queue=new LinkedList<>();
    }
    
    public void push(int x) {
        queue.add(x);
    }
    
    public int pop() {
        for(int i=0;i<queue.size()-1;i++){
            queue.add(queue.remove());
        }
        return queue.remove();
    }
    
    public int top() {
        int res=this.pop();
        this.push(res);
        return res;
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }
}

Java集合常见面试题总结(上)

JavaGuide原文链接

你可能感兴趣的:(leetcode,算法,职场和发展)