[编程题]剑指 Offer 09 用两个栈实现队列(四种方式[本质是2种方法])

lc 剑指 Offer 09. 用两个栈实现队列

题目描述

image-20200720113109874

输入输出描述

image-20200720113130437

思路

1、使用传统的栈Stack即可完成

2、使用Deque数据结构堵住一端(堵住首)----(addLast(),removeLast) 或者堵住尾(addFirst();removeFirst)

3、使用Deque数据结构堵住一端(堵住尾(addFirst();removeFirst)

4、直接使用Deque模拟栈方法push,pop;即可 (其中就是底层使用的3的方法)

方法1:使用传统的栈Stack即可完成

Java代码:

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        //pop的时候直接看栈2是否为空
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
            //都存入栈2中的时候,调用一次pop方法,弹出一个stack2的栈顶元素(但是每次弹出都判断栈是否空)
            if(!stack2.isEmpty()) {
                return stack2.pop();
            }else { return -1; }    
        }else{
            //栈2不为空,直接弹出我们需要的栈顶元素(每次弹出每次检测栈是否空)
            if(!stack2.isEmpty()) {
                return stack2.pop();
            }else { return -1; }   
        }
    }
}

输出:

时间和内存如下:

image-20200720114108771

方法2:使用Deque数据结构堵住一端(堵住尾(addFirst();removeFirst)

相当于我们堵住双端列表的尾部,从前边存取。

addFirst();removeFirst)

如下:

image-20200720115137730

Java代码

import java.util.*;

public class Solution {
    Deque<Integer> stack1 = new LinkedList<>();
    Deque<Integer> stack2 = new LinkedList<>();
    
    public void push(int node) {
       stack1.addFirst(node);
    }
    
    public int pop() {
        //如果栈2空,先进行转移操作
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.addFirst(stack1.removeFirst());
            }
            //把stack1元素都放入到stack2后可以弹出栈首,(每次都要检测是否栈为空)
            if(!stack2.isEmpty()){return stack2.removeFirst();}
            else {return -1;}
        }else{
            //栈2不为空
            //弹出栈首,(每次都要检测是否栈为空)
            if(!stack2.isEmpty()){return stack2.removeFirst();}
            else {return -1;}
        }
       
    }
}

输出:

image-20200720115756177

方法3:使用Deque数据结构堵住一端(堵住首)----(addLast(),removeLast)

思想

addLast(),removeLast)

image-20200720115414859

Java代码

import java.util.*;
class CQueue {
    
    Deque<Integer> stack1;
    Deque<Integer> stack2;


    public CQueue() {
        stack1 = new LinkedList<Integer>();
        stack2 = new LinkedList<Integer>();
    }
    
    //Deque是双端的队列,我们只要保证一端不变就是栈,比如头不变,往后插,从后取就是栈
    public void appendTail(int value) {
        stack1.addLast(value);
    }
    
    public int deleteHead() {
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.addLast(stack1.removeLast());
            }
            //放完之后取出stack2的最后的一个元素(因为模拟栈的话,统一看做First是堵住的)
            //注意出队的时候一定要时刻判断队是否为空
            if(!stack2.isEmpty()){return stack2.removeLast();}else{return -1;} 
        }else{
            //stack2不为空,就直接弹出
            //注意出队的时候一定要时刻判断队是否为空
            if(!stack2.isEmpty()){return stack2.removeLast();}else{return -1;}
        }
    }
}

方法4:直接使用Deque模拟栈方法push,pop;即可 (其中就是底层和方法2addFisrt原理相同)

java代码:

import java.util.*;

public class Solution {
    Deque<Integer> stack1 = new LinkedList<Integer>();
    Deque<Integer> stack2 = new LinkedList<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        //如果栈2为空,就先转移栈1元素如栈2
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
            //压栈完成后,就可以本次的弹出操作(每次都要检测本次出栈栈2空了吗)
            if(!stack2.isEmpty()){return stack2.pop();}
            else return -1;
        }else{
            //如果栈2本身不为空,直接出栈
            if(!stack2.isEmpty()){return stack2.pop();}
            else return -1;
        }
    }
}

输出:

image-20200720120236886

原文地址:https://www.cnblogs.com/jiyongjia/p/13344340.html