理论文章:栈与队列part1
leetcode232:用栈实现队列
讲解文章:leetcode232
leetcode225:用队列实现栈
讲解文章:leetcode225
目录
1,leetcode232 用栈实现队列
1.1 我的实现
由于栈和队列我比较熟,也经常用,就直接看题。
用栈实现队列肯定是需要两个栈的,原因就是栈只能在一端操作,另一端没有任何操作,而队列是两端操作的,因此必须使用一个栈倒腾一下,把整个栈倒过来才能操作。
class MyQueue {
private:
stack<int>que1;
stack<int>que2;
public:
MyQueue() {
}
void push(int x) {
que1.push(x);
}
int pop() {
int size = que1.size()-1;
while(size--){
que2.push(que1.top());
que1.pop();
}
int result = que1.top();
que1.pop();
while(!que2.empty()){
que1.push(que2.top());
que2.pop();
}
return result;
}
int peek() {
int size = que1.size()-1;
while(size--){
que2.push(que1.top());
que1.pop();
}
int result = que1.top();
while(!que2.empty()){
que1.push(que2.top());
que2.pop();
}
return result;
}
bool empty() {
return que1.empty();
}
};
/**
* 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();
*/
队列是先进先出的,因此队列开头的操作实际上都是对栈底部元素的操作。每次读取队首元素或者从队首删除元素的时候,就需要que2这个栈承接一下倒腾出来的元素。而操作完后也需要将que1和que2复原回去。
1.2 代码复用
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stIn.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
// 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
if (stOut.empty()) {
// 从stIn导入数据直到stIn为空
while(!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
/** Get the front element. */
int peek() {
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
/** Returns whether the queue is empty. */
bool empty() {
return stIn.empty() && stOut.empty();
}
};
代码随想录这个代码最重要的地方在于划分了两个栈的实际意义,一个栈是输入顺序的栈,另一个栈是输出顺序的栈,每次需要pop的时候更新这个stout,在这样的设计下,pop部分的代码就可以重用了,也不需要每次再倒腾回stin这个栈里,时间消耗上要远小于我的做法。
2,用队列实现栈
很容易就发现,用队列实现栈就根本不需要两个队列,原因就是队列本来就能对两端元素进行操作,因此像是top只要取队尾元素就行了,而pop思路也很简单,由于每次都是弹出栈顶,也就是队尾元素,那么只需要把队尾之前的元素全弹出来再放回队列中,这样队尾变队首直接弹出即可。
class MyStack {
private:
queue<int> qsta;
public:
MyStack() {
}
void push(int x) {
qsta.push(x);
}
int pop() {
int size = qsta.size()-1;
while (size--) {
qsta.push(qsta.front());
qsta.pop();
}
int result = qsta.front();
qsta.pop();
return result;
}
int top() {
return qsta.back();
}
bool empty() {
return qsta.empty();
}
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
和随想录思路一致。