算法学习|Day10 栈part01|Leetcode 232 用栈实现队列 225 用队列实现栈

1. 232 用栈实现队列 E

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

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

1.1 思路分析

  • 这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。

  • 使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈==一个输入栈,一个输出栈==,这里要注意输入栈和输出栈的关系。

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

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

  • 在代码实现的时候,会发现pop() 和 peek()两个函数功能类似,代码实现上也是类似的,可以思考一下如何把代码抽象一下。

1.2 解题代码

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() {
        //判断是否为空:若in不空,out为空:false&&true=false,即不空
        return stackIn.isEmpty()&& stackOut.isEmpty();
    }

    private void dumpStackIn(){
        if (!stackOut.isEmpty()) {
            return;
        }
        while (!stackIn.isEmpty()) {
            stackOut.push(stackIn.pop());
        }
    }
}

1.3 总结及注意

  1. pop() 和 peek()两个函数功能类似,可以单独把他们共用的部分抽象出来构造一个新的函数,比如此题中新创建的dumpStackIn()函数。
  2. 本题不涉及什么高深的算法知识,就是用两个栈模拟队列的行为;

2. 225 用队列实现栈 E

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppopempty)。

实现 MyStack 类:

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

2.1 思路分析

用一个队列进行模拟,将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时弹出元素顺序就是栈的顺序。

2.2 解题代码

class MyStack {
    Queue<Integer> queue;

    public MyStack() {
        queue=new LinkedList<>();
    }
    
    public void push(int x) {
        queue.add(x);
    }

    //移出并返回
    public int pop() {
        rePositon();
        return queue.poll();
    }

    //返回栈顶
    public int top() {
        //把前面的元素都移出
        rePositon();
        //队列函数poll 返回队首元素并删除
        int result=queue.poll();
        //重新添加回去
        queue.add(result);
        return result;
    }
    
    public boolean empty() {
        return queue.isEmpty();
    }

    private void rePositon(){
        int size= queue.size();
        size--;
        while (size-- > 0) {
            queue.add(queue.poll());
        }
    }
}

3. 栈和队列方法汇总

3.1 栈

  1. push():在栈的顶部插入一个元素。
  2. pop():返回栈顶元素,并将其删除。
  3. peek():返回栈顶元素,但是不会将其删除。
  4. empty():判断栈是否为空,如果为空则返回true,否则返回false。
  5. search(Object o):返回元素在栈中的位置,如果元素不存在,则返回-1。

这些方法常用于实现基于栈的数据结构,如表达式求值、回文字符串判断等。在使用栈的方法时,应将栈声明为具体的类,如Stack、ArrayDeque等。需要注意的是,由于LinkedList实现了Deque接口,因此它也可以用来作为栈的实现。

3.2 队列

  1. offer():将元素插入队尾,返回是否成功插入。
  2. add():为队列插入元素,如果队列已满,则抛出IllegalStateException异常。
  3. element():返回队列头部的元素,但是不会将其删除。
  4. peek():返回队列头部的元素,但是不会将其删除。如果队列为空,则返回null。
  5. poll():返回队列头部的元素并将其删除,如果队列为空,则返回null。
  6. remove():返回队列头部的元素并将其删除。如果队列为空,则抛出NoSuchElementException异常。
  7. size():返回队列中元素的数量。

这些方法常用于实现基于队列的数据结构,如生产者-消费者模型等。注意,在使用队列方法时,应将队列声明为具体的类,如LinkedList、ArrayDeque等。

PS:

在Java中,队列的方法中有两个方法可以用于添加元素,一个是offer(Object o)方法,另一个是add(Object o)方法,两者在功能上有一些不同。具体来说:

  1. offer(Object o)方法将指定的元素插入到队列的末尾,如果队列已满,则返回false,否则返回true。
  2. add(Object o)方法也将指定的元素插入到队列的末尾,但是如果队列已满,则抛出IllegalStateException异常。

因此,offer(Object o)方法通常用于具有限制容量的队列,如阻塞队列或有大小限制的队列,因为该方法可以返回一个表示是否成功插入元素的布尔值。而add(Object o)方法则不适用于具有限制容量的队列,因为如果在队列满的情况下使用add()方法,则会引发异常。

综上所述,如果对于具有容量限制的队列而言,如果必须确保元素被添加到队列中,则应使用add(Object o)方法;如果可以容忍失败的情况,则可以使用offer()方法。而对于不是限制容量的队列,例如LinkedList,两个方法没有任何功能上的差异。

3.3 比较

方法队列
添加元素push()offer()
返回元素,并删除pop()poll()
返回元素但不删除peek()peek()
判断为空empty()isEmpty()
获取元素数不适用size()
查找元素位置search(Object o)不适用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值