Problem:
As the title described, you should only use two stacks to implement a queue’s actions.
The queue should support push(element), pop() and top() where pop is pop the first(a.k.a front) element in the queue.
Both pop and top methods should return the value of first element.
解法1:我最开始的版本solution push(), pop()和top()三个都是O(n)级别。
class MyQueue {
public:
MyQueue() {
// do intialization if necessary
}
/*
* @param element: An integer
* @return: nothing
*/
void push(int element) {
int num;
while(!s2.empty()) {
num = s2.top();
s2.pop();
s1.push(num);
}
s1.push(element);
}
/*
* @return: An integer
*/
int pop() {
int num;
while (!s1.empty()) {
num = s1.top();
s1.pop();
s2.push(num);
}
if (!s2.empty()) {
num = s2.top();
s2.pop();
return num;
}
return INT_MIN;
}
/*
* @return: An integer
*/
int top() {
int num;
while (!s1.empty()) {
num = s1.top();
s1.pop();
s2.push(num);
}
if (!s2.empty())
return s2.top();
return INT_MIN;
}
private:
stack<int> s1, s2;
};
解法2:
研究了一下网上的版本,发现push()是可以改进的。其实只有当s2是empty()的时候才需要把s1的元素倒过来。改进版本如下:
class MyQueue {
public:
MyQueue() {
// do intialization if necessary
}
/*
* @param element: An integer
* @return: nothing
*/
void push(int element) {
s1.push(element);
}
/*
* @return: An integer
*/
int pop() {
int num;
if (s2.empty()) {
while (!s1.empty()) {
num = s1.top();
s1.pop();
s2.push(num);
}
}
if (!s2.empty()) {
num = s2.top();
s2.pop();
return num;
}
return INT_MIN;
}
/*
* @return: An integer
*/
int top() {
int num;
if (s2.empty()) {
while (!s1.empty()) {
num = s1.top();
s1.pop();
s2.push(num);
}
}
if (!s2.empty())
return s2.top();
return INT_MIN;
}
private:
stack<int> s1, s2;
};
代码同步在
https://github.com/luqian2017/Algorithm
三刷:
class MyQueue {
public:
MyQueue() {
// do intialization if necessary
}
/*
* @param element: An integer
* @return: nothing
*/
void push(int element) {
s1.push(element);
}
/*
* @return: An integer
*/
int pop() {
int res = 0;
if (s2.empty()) {
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
}
res = s2.top();
s2.pop();
return res;
}
/*
* @return: An integer
*/
int top() {
if (s2.empty()) {
while (!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
}
return s2.top();
}
private:
stack<int> s1, s2;
};
注意我上面说的时间复杂度分析是错误的。这里的push(),pop()和top()的时间复杂度平均都是O(1),因为每个元素平均也就进q1和q2,出q1和q2一次,所以一均摊时间复杂度就是O(1)。这是跟LintCode-494: Implement Stack by Two Queues这题不一样的地方,那题pop的时间复杂度为O(n)。
四刷: 这个版本不好。
class MyQueue {
public:
MyQueue() {
}
void push(int x) {
stk1.push(x);
}
int pop() {
while(!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
int top = stk2.top();
stk2.pop();
while(!stk2.empty()) {
stk1.push(stk2.top());
stk2.pop();
}
return top;
}
int peek() {
while(!stk1.empty()) {
stk2.push(stk1.top());
stk1.pop();
}
int top = stk2.top();
//stk2.pop();
while(!stk2.empty()) {
stk1.push(stk2.top());
stk2.pop();
}
return top;
}
bool empty() {
return stk1.empty() && stk2.empty();
}
private:
stack<int> stk1, stk2;
};
/**
* 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();
* bool param_4 = obj->empty();
*/