实现一个队列,使得push_rear(), pop_front() 和get_min()的时间复杂度为O
Posted ChainingBlocks
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现一个队列,使得push_rear(), pop_front() 和get_min()的时间复杂度为O相关的知识,希望对你有一定的参考价值。
问题描述:
实现一个队列,使得它的push_rear(), pop_front() 和get_min() 这三个函数的时间复杂的为常数(即O(1))。
分析:
在leetcode上面有类似的题目,但是其所要求的是实现一个栈(stack)而不是队列。
这里将使用两个栈来作为辅助数据结构。第一个栈专门用来接收新来的数据,第二个栈专门接收第一个栈中的数据。每一次都把第一个栈中的所有数据倒转到第二个中。数据永远从第二个栈中pop出去。
具体举例来看:现在四个数字[1, 5, 2, 4] (4是最早到达的数据)依次压入栈中,每压入一个数字的时候,在其旁边(黄色背景)使用另一个数字记录当前栈中最小的值。所以,从下图中,当压入数字5的时候,当前栈中最小的值是2,所以其旁边的数字为2.
四个数字入栈之后,把它们分别弹出然后再次入栈到第二个栈中。黄色背景的数值依然是记录当前栈中最小的数字。当需要pop front操作的时候,把第二个栈中top元素弹出。
这时候发现,这三个函数push_rear(), pop_front() 和get_min()的时间复杂度是为O(0)的。算法运行期间间歇性的将数据从栈1中倒转到栈2中,这个操作所用的时间复杂度为O(n),但是因为并不是在操作每一个元素的时候都需要倒转,所以平均下来整个算法的三个函数的时间复杂度是常数。
实现
import java.util.EmptyStackException;
import java.util.Stack;
public class ContantQueue
private Stack<Value> s1 = new Stack<>();
private Stack<Value> s2 = new Stack<>();
public void pushRear(int value)
System.out.println("input number: "+value);
pushRear(s1, value);
private void pushRear(Stack<Value> s, int value)
if(s.empty())
s.push(new Value(value, value));
else
if(value > s.peek().min)
s.push(new Value(value, s.peek().min));
else
s.push(new Value(value, value));
public int popFront()
if(empty()) throw new EmptyStackException();
return s2.pop().value;
public int getMin()
if(empty()) throw new EmptyStackException();
return s2.peek().min;
public boolean empty()
if(s2.empty())
transferNums();
if(s2.empty()) return true;
else return false;
private void transferNums()
if(s1.empty()) return;
while(!s1.empty())
pushRear(s2, s1.pop().value);
class Value
int value;
int min;
public Value()
public Value(int value, int min)
this.value = value;
this.min = min;
public static void main(String[] args)
ContantQueue queue = new ContantQueue();
queue.pushRear(4);
queue.pushRear(2);
queue.pushRear(5);
queue.pushRear(1);
assert queue.popFront() == 4;
assert queue.popFront() == 2;
assert queue.popFront() == 5;
assert queue.popFront() == 1;
queue.pushRear(6);
queue.pushRear(2);
queue.pushRear(9);
queue.pushRear(7);
assert queue.popFront() == 6;
assert queue.getMin() == 2;
assert queue.popFront() == 2;
assert queue.getMin() == 7;
queue.pushRear(16);
queue.pushRear(8);
assert queue.popFront() == 9;
assert queue.popFront() == 7;
assert queue.popFront() == 16;
assert queue.popFront() == 8;
该代码实现只适用于单线程。
结束!
以上是关于实现一个队列,使得push_rear(), pop_front() 和get_min()的时间复杂度为O的主要内容,如果未能解决你的问题,请参考以下文章