232.用栈实现队列
最开始的思路是想能不能建两个栈,一个正序存储负责进队列功能,一个反序存储负责出队列功能。这样能够实现批量进队后再批量出队。但是如果交替进行进出队列的操作就不行了。
思路:使用一个进栈和一个出栈模拟队列。需要进队列时将所有元素移动到进栈,进栈的栈顶为队列尾;需要出队列时将所有元素移动到出栈,出栈的栈顶为队列头
(相当于两个栈是两个杯子,需要某一个杯子的功能时就将另外一个杯子的水全倒入该杯子中)
· 由于栈进出数据的特点,将一个栈的元素逐个弹出并存入另一个栈,最后这两个栈中元素的顺序一定是反的。
class MyQueue {
public:
MyQueue() {
}
// 将所有出栈元素移入进栈
// 在进栈的栈顶push元素
void push(int x) {
while (!stackOut.empty()) {
stackIn.push(stackOut.top());
stackOut.pop();
}
stackIn.push(x);
}
// 将所有进栈元素移入出栈
// 将出栈的栈顶元素pop并返回
int pop() {
while (!stackIn.empty()) {
stackOut.push(stackIn.top());
stackIn.pop();
}
int res = stackOut.top();
stackOut.pop();
return res;
}
// 执行this的pop函数
// 此时出栈栈顶元素被pop,记录该元素,将其再放回出栈栈顶
int peek() {
int res = this->pop();
stackOut.push(res);
return res;
}
// 如果进出栈都是空的说明队列是空的
bool empty() {
return stackIn.empty() && stackOut.empty();
}
stack<int> stackIn; // 进栈
stack<int> stackOut; // 出栈
};
225.用队列实现栈
(由于队列相比于栈有两个口,所以相比于232这题会简单很多)
思路:队列两个口能连通形成循环,那么需要队列尾(即模拟的栈顶)元素时,只要将其循环到队列头即可获取。
class MyStack {
public:
MyStack() {
size = 0;
}
// 直接加到队列尾
void push(int x) {
queueStack.push(x);
++size;
}
// 将队尾元素移到队头
int pop() {
int res;
// 不断将队头元素移到队尾,直到最开始的队尾到达队头
for (int i = 0; i < size - 1; ++i) {
res = queueStack.front();
queueStack.pop();
queueStack.push(res);
}
// 弹出此时的队头,即原先的队尾
res = queueStack.front();
queueStack.pop();
--size;
return res;
}
//int top() {
// int res = this->pop();
// queueStack.push(res);
// // 注意pop的实现中size被-1,这里要加回来
// ++size;
// return res;
//}
// 直接返回队列的back就行
int top() {
return queueStack.back();
}
bool empty() {
return queueStack.empty();
}
queue<int> queueStack;
int size; // 其实不需要,queue自己就有.size()方法
};
今天的题偏简单,主要加深对stack和queue内部实现机制的理解