刷题day9 栈与队列理论基础、232用栈实现队列、225用队列实现栈

一、栈与队列理论基础

队列:先进先出

栈:先进后出

栈提供push和pop等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)不像是set或者map提供迭代器iterator来遍历所有元素

栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可插拔的(也就是说我们可以控制使用那种容器来实现栈的功能)

所以STL(C++标准库)中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。

二、232用栈实现队列

这道题先要明白栈里自己自带的函数有push() pop() peek() ,这个一开始困惑了好久 我以为是无限调用自己定义的函数,之后陷入了循环,没有解决出来

然后要注意的问题是可不可以封装抽象一部分函数,供pop和peek一起使用呢

因为这两个函数的逻辑都是返回栈顶的元素

我们是要用栈来实现队列,所以对于栈来说肯定是要用两个栈,并且是先进栈,再出栈进入另一个栈,所以要创建两个栈对象,Stack<Integer> Stackin;Stack<Integer> Stackout;

在这里注意一下Stack<Integer>这是一个泛型类,所以只会接受引用类型作为参数,不是接受基本数据类型,而Integer是引用类型,int是基本数据类型,不能放在这里,只能放引用类型,Integer是int的包装,

在 Java 中,String 是引用类型,不是基本类型。尽管 String 在 Java 中使用非常广泛,但它实际上是一个类而不是原始数据类型。Java 中的原始数据类型是 intcharboolean 等,而 String 是一个对象,它是 Java 中的一个类。

第一个函数是创建队列,那么就用栈引用指向栈对象 Stackin = new Stack<>();Stacakout = new Stack(); 第二个函数直接入队 也就是Stackin进栈即可,第三个函数弹出Stackout的栈顶元素也就是队列的最开始入队的元素,但是这里需要注意了,如果Stackout的栈里没有元素那么就要从Stackin的栈里出栈元素

所以这部分抽象出来 先判断一下Stackout栈里是不是空,如果不是空,直接返回弹就完事了;如果是空,那么就要while循环Stackin是不是空,如果他也不是空,就循环把Stackin的值弹到Stackout中

因为这个整个过程是看Stackout里有没有值,如果他的值用完了,就从Stackin中弹。而对于他的操作就是push(Stackin.pop())里的值

之后的一个empty函数是判断队列是否是空的,直接return Stackin.isEmpty() && Stackout.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() {
        dumpStackin();
        return Stackout.pop();
    }
    
    public int peek() {
        dumpStackin();
        return Stackout.peek();
    }
    
    public boolean empty() {
        return Stackin.isEmpty() && Stackout.isEmpty();
    }
    private void dumpStackin(){
    if(!Stackout.isEmpty())
        return;
    while(!Stackin.isEmpty()){
        Stackout.push(Stackin.pop());
    }
  }
}



/**
 * 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();
 */

三、225.用队列实现栈

这道题主要是直到队列里的常用函数其实就好做了,队列里通常有addFirst(),addLast(x),pollFirst(),pollLast(),peekFirst(),peekLast()这些函数

这里还需要注意一点,这里实例化队列对象的时候,只能是用实现了Deque接口的类来实例化,不能用Deque自己实例化,但是可以用接口类型创建变量 Deque<Integer> que1;而这里Deque<Integer> que1; 这行代码是在声明一个名为 que1 的变量,其类型是 Deque,这意味着它可以引用任何实现了 Deque 接口的类的对象。在这种情况下,你可以将 que1 引用具体实现了 Deque 接口的类的对象,例如 ArrayDeque

这道题只用了一个队列,就解决了,其他的操作都可以直接实现比如说创建栈的函数 直接就是实例化一个队列对象就好了 que1 =  new ArrayDeque(); 用que1去引用这个对象

压栈的过程可以直接调用que1.addLast(x)

输出栈顶元素可以这样做:可以先把队列的数量减一,然后把栈顶元素之前的元素全部移到队尾,这个过程就是一个入队还有出队的过程,队尾入队,队头出队,即que1.addLast(que1.peekFirst());que1.pollFirst();

然后正好循环结束就会剩下最后一个元素,因为我预先减了一,出了循环直接弹出栈顶元素,然后返回int res = que1.pollFirst();return res;

之后返回栈顶元素的函数其实就是返回队尾元素return que1.peekLast();

判断空的函数就是队列是否为空return que1.isEmpty();

代码如下:

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--;
        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();
    }
}

/**
 * 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();
 */

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值