两个栈实现一个队列

一个很常见的面试题,用两个栈 Stack 实现队列 Queue。分别写了最简单最容易想到的做法,和优化后的做法。

最初思路:

Stack 是先进后出 FILO,Queue 是先进先出 FIFO,所以如果想在出队时简单地使用栈的 pop() 方法的话,那么入队时就要保证将元素放到栈底,而不是像 Stack.push(x) 那样放到栈顶,这样就实现了最后放入的最后出来。所以只要将栈中原有元素全部倒出来,放入另一个临时栈中,然后把 x 放到栈底,再将临时栈中的元素倒回来,就 OK 了。

Java 实现:

import java.util.Stack;

public class MyQueue {

     Stack<Object> _data = new Stack<Object>();

     public void enqueue(Object x){

          Stack<Object> temp = new Stack<Object>();

          while (!_data.isEmpty()) {

               temp.push(_data.pop());

          }

          _data.push(x);

          while (!temp.isEmpty()){

               _data.push(temp.pop());

          }

     }

     public Object dequeue() {

          return _data.pop();

     }

}

当然了,还可以在入队时简单的使用栈的 push(x) 方法,这样就需要在出队时,拿出栈底元素,而非栈顶元素,方法是一样的:

import java.util.Stack;

public class MyQueue {

     Stack<Object>_data = new Stack<Object>();

     public void enqueue(Object x){

          _data.push(x);

     }

     public Object dequeue() {

          Object reval = new Object();

          Stack<Object> temp = new Stack<Object>();

          while (!_data.isEmpty()) {

               temp.push(_data.pop());

          }

          reval = temp.pop();

          while (!temp.isEmpty()){

               _data.push(temp.pop());

          }

          return reval;

     }

}

优化:

但是,以上的做法并不高效,因为每进行一次入队/出队操作,都要将元素倒进 temp 再倒回来。更好的做法是,只有到了必要的时候,才进行“倒”的工作。

方法是使用两个栈s1, s2。s1用来入队,s2用来出队,入队时直接调用 s1.push(x),出队时直接调用 s2.pop();但若 s2 为空,此时将 s1 中的全部元素倒给 s2。

此法同样也是通过两个栈的反序,“反反得正”,得到队列顺序,实现了先进的元素先出来,但是只有 s2 “库存”为零,没得给的时候才从 s1 中取元素,提高了效率。

Java 实现:

import java.util.Stack;

public class MyQueue {

     Stack<Object> s1 = new Stack<Object>();

     Stack<Object> s2 = new Stack<Object>();

     public void enqueue(Object x){

          s1.push(x);

     }

     public Object dequeue() {

          if (s2.isEmpty()) {

               while (!s1.isEmpty()) {

                     s2.push(s1.pop());

               }

          }

          return s2.pop();

     }

}

测试结果:

public class Tester {

     public static void main(String[]args) {

          MyQueue queue = new MyQueue();

          queue.enqueue(1);

          queue.enqueue(2);

          queue.enqueue(3);

          System.out.println(queue.dequeue());

          System.out.println(queue.dequeue());

          System.out.println(queue.dequeue());

     } 

}

输出:

1

2

3

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值