标签:元素 标准 代码 from pop 两种方法 一个栈 OLE move
使用队列实现栈的下列操作:
注意:
push to back
, peek/pop from front
, size
, 和 is empty
这些操作是合法的。这里就需要另外一个队列来辅助操作,我们总共需要两个队列,其中一个队列用来放最后加进来的数,模拟栈顶元素。剩下所有的数都按顺序放入另一个队列中。
当 push() 操作时,将新数字先加入模拟栈顶元素的队列中,如果此时队列中有数字,则将原本有的数字放入另一个队中,让新数字在这队中,用来模拟栈顶元素。
当 top() 操作时,如果模拟栈顶的队中有数字则直接返回,如果没有则到另一个队列中通过平移数字取出最后一个数字加入模拟栈顶的队列中。
当 pop() 操作时,先执行下 top() 操作,保证模拟栈顶的队列中有数字,然后再将该数字移除即可。当 empty() 操作时,当两个队列都为空时,栈为空。代码如下:
class MyStack {
public:
MyStack() {}
void push(int x) {
q2.push(x);
while (q2.size() > 1) {
q1.push(q2.front()); q2.pop();
}
}
int pop() {
int x = top(); q2.pop();
return x;
}
int top() {
if (q2.empty()) {
for (int i = 0; i < (int)q1.size() - 1; ++i) {
q1.push(q1.front()); q1.pop();
}
q2.push(q1.front()); q1.pop();
}
return q2.front();
}
bool empty() {
return q1.empty() && q2.empty();
}
private:
queue<int> q1, q2;
};
下面这种方法,比较好记,只要实现对了 push() 函数,后面三个直接调用队列的函数即可。
这种方法的原理就是每次把新加入的数插到前头,这样队列保存的顺序和栈的顺序是相反的,它们的取出方式也是反的,那么反反得正,就是我们需要的顺序了。
我们可以使用一个辅助队列,把q的元素也逆着顺序存入到辅助队列中,此时加入新元素x,再把辅助队列中的元素存回来,这样就是我们要的顺序了。
当然,我们也可以直接对队列q操作,在队尾加入了新元素x后,将x前面所有的元素都按顺序取出并加到队列到末尾,这样下次就能直接取出x了,符合栈到后入先出到特性,其他三个操作也就直接调用队列的操作即可,参见代码如下:
class MyStack {
public:
MyStack() {}
void push(int x) {
q.push(x);
for (int i = 0; i < (int)q.size() - 1; ++i) {
q.push(q.front()); q.pop();
}
}
int pop() {
int x = q.front(); q.pop();
return x;
}
int top() {
return q.front();
}
bool empty() {
return q.empty();
}
private:
queue<int> q;
};
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
for(int i = 1; i < queue.size(); i++)
queue.add(queue.remove());
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.size() == 0;
}
}
上面两种解法对于不同的输入效果不同,解法一花在 top() 函数上的时间多,所以适合于有大量 push() 操作,而 top() 和 pop() 比较少的输入。而第二种解法在 push() 上要花大量的时间,所以适合高频率的 top() 和 pop(),较少的 push()。两种方法各有千秋,互有利弊。
标签:元素 标准 代码 from pop 两种方法 一个栈 OLE move
原文地址:https://www.cnblogs.com/wwj99/p/12388916.html