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

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

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

在这里插入图片描述

很多人看不懂题目,博主刚开始也是萌萌,简单明了,带你直接看懂题目和例子。 输入: [“CQueue”,“appendTail”,“deleteHead”,“deleteHead”] 这里是要执行的方法,从左到右执行
[[],[3],[],[]]对应上面的方法,是上面方法的参数。CQueue和deleteHead方法不需要指定数字,但deleteHead要返回被删除元素,只有appendTail添加才需要指定数字,但无返回值

1.创建队列,返回值为null
2.将3压入栈,返回值为null
3.将栈底的元素删除,也就是消息队列中先进来的元素,所以是deleteHead,返回该元素的数值,所以为3
4.继续删除栈底的元素,但是没有元素了,所以返回-1

所以就有了下面的输出 输出:[null,null,3,-1]

示例 2: 输入: [“CQueue”,“deleteHead”,“appendTail”,“appendTail”,“deleteHead”,“deleteHead”]
[[],[],[5],[2],[],[]]:

1.创建队列,返回值为null
2.删除栈底的元素,但是没有元素,所以返回-1
3.把5压入栈,返回null
4.把2压入栈,返回null
5.删除栈底的一个元素,也就是消息队列中先进来的元素,所以是deleteHead,就是最先进来的5,返回值为5,
6.删除栈底的一个元素,就是后进来的2,返回值为2,

所以就有了下面的输出

输出:[null,-1,null,null,5,2]

有没有发现先进来的数字,首先显示出来了,但是题目中说要使用栈,栈是先进后出的,使用栈来实现先进先出,在这里使用两个栈就好了,从一个进来再出去到另一个栈就是要删除的顺序,这样顺序就是先进先出了。题目的主旨写在第一句,就是,使用两个栈实现一个队列。

public class CQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    //创建队列,无参数,返回null
    public CQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    // appendTail 参数为value,将数据压入栈中无返回值;
    public void  appendTail(int value){
         stack1.push(value);
    }
    // 删除先压入栈的值,返回这个值。若为null,返回-1
    public int deleteHead(){
        //使用if(stack2 == null) 错误
        if(stack2.isEmpty()) {
                    //stack1.empty
            while (!stack1.isEmpty()) {
                //之前显示pop()返回是object类型,所以使用stack2.push(Integer.parseInt(stack1.pop().toString()));
                stack2.push(stack1.pop());
            }
        }
        /*else if(stack2.isEmpty()),如果写成这样,上面的if执行完了没有返回的语句,会提醒缺少return
        if ,else if,else,是满足条件执行一个。下面改成if if是都会执行
        return两个作用1.返回结果2.结束函数。
        怎么使用return:当找到我想要的结果时
        使用几个:循环找到就可使用提前结束循环,返回结果。循环结束没找到,也要返回return null
        */
         if(stack2.isEmpty()){
                return -1;
            }

        else{
            int value = stack2.pop();
            return value;
        }
    }
}

整体思路:
1、创建一个队列,需要用两个栈来实现
2.添加appendTail()中需要传入添加数据的参数,但无需返回值。用Stack的push直接压入栈底即可
3.删除deleteHead()不需传入参数,但需返回删除的元素值。Stack 是先进后出,与队列的性质先进先出不同,所以要再使用一个栈来控制删除的顺序,第一个栈是push进入的数据,顺序是先进的再最下面,而我们要将他最先删除,就需要借助第二个栈,让第一个栈中push进入的数据pop出去,这样最后进入的就在最下面,先进入的再最上面这样就可以完成删除的操作。
需要注意的是deleteHead()的注释部分是博主踩过的坑。

还有两个不理解的地方:
1.stack2 == null和stack2.isEmpty()不同吗?
应该是不能用==null判断为空,结果会出错。
2 stack1.empty()和stack1.isEmpty()不同之处?
java.util.Stack类中,size()方法是使用的java.util.Vector的size()方法,那么从源码上看,empty()和isEmpty()两者无本质区别
当判断一个栈是否为空时,使用stack.empty()与stack.isEmpty()均可,只是两个方法存在的类不同。

3.之前显示pop()返回是object类型,所以使用stack2.push(stack1.pop())提示我需要类型转换。为什么只会就不提示了呢

因为提示要类型转换,所以特意搜集了两个object转integer的方法

1.先转为String类型,再转为Integer

Objcet obj;
int a= Integer.parseInt(obj.toString());

2.先把object强转成Long,再转为int

Object obj ;
Long long = (Long) obj;
int a= long.intValue();

如果你们有好的意见或者建议可以直接评论,希望有人可以解答我的疑惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值