力扣232.用栈实现队列和225.用队列实现栈,在2024年3/3和3/4连续两天出现,正好也回顾一下数据结构,前一年我一直在学习Godot游戏开发和美术,原来的C++老本行都要忘了,最近一段时间才重操旧业,还是先从简单做起。
这两题都是非常经典的数据结构题,属于简单题,我这里也就给出比较常见的方法。
先看两道题目如下:
第一个题目,用栈实现队列,就是要用两个具有先进后出特性的stack来实现一个先进先出特性的queue,我的思路其实就是把两个stack来回倒腾一遍,因为每次pop()或是peek()都是要获得栈底的元素,那我把stack1的元素按先进后出的规则移动到stack2时,此时stack2的元素顺序和stack1时相反的,此时原来stack1栈底的元素转移到了stack2的栈顶,此时就能够获取到了。
class MyQueue {
public:
stack<int>stack1;
stack<int>stack2;
MyQueue() {
}
void push(int x) {
stack1.push(x);
}
int pop() {
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
int a =stack2.top();
stack2.pop();
while(!stack2.empty()){
stack1.push(stack2.top());
stack2.pop();
}
return a;
}
int peek() {
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
int a =stack2.top();
while(!stack2.empty()){
stack1.push(stack2.top());
stack2.pop();
}
return a;
}
bool empty() {
return stack1.empty();
}
};
这个代码当时我草草就写了,现在看着实在是冗长。。。
第二题,要用两个具有先进先出特性的queue来实现一个先进后出特性的stack,最主要的就是push方法的实现,这里的思路是:每次尾插元素的时候,都先加在第二个队列queue2里面,然后再让原有的queue1里面的元素依次从头到尾移到queue2里面,这样一来,刚才最新加入的元素就成了queue2里面的首个元素,再交换两个队列,其他方法都使用queue1。
void push(int x) {
queue2.push(x);
while (!queue1.empty()) {
queue2.push(queue1.front());
queue1.pop();
}
swap(queue1, queue2);
}
当然,还有只用到一个queue的方法,就是每次移除的时候,一个queue如果长n,要模拟stack,就是要移除第n个元素,那么可以先执行记录第1个元素a,删除第一个元素,把记录a添加到queue末尾,这样循环n-1次后,就会发现,原来位于第n的元素变成了第1位元素,其他的元素都后移了一位,此时pop()第1个元素,实现了stack的效果,而且其他元素的顺序保持不变。
class MyStack {
public:
queue<int>queue1;
MyStack() {
}
void push(int x) {
queue1.push(x);
}
int pop() {
int n =queue1.size()-1;
for(int i=0;i<n;i++){
queue1.push(queue1.front());
queue1.pop();
}
int temp = queue1.front();
queue1.pop();
return temp;
}
int top() {
return queue1.back();
}
bool empty() {
return queue1.empty();
}
};