算法
(栈,队列) $O(n)$
这是一道基础题,只要把功能实现对就可以,不需要考虑运行效率。
我们用两个栈来做,一个主栈,用来存储数据;一个辅助栈,用来当缓存。
push(x)
,我们直接将x插入主栈中即可。pop()
,此时我们需要弹出最先进入栈的元素,也就是栈底元素。我们可以先将所有元素从主栈中弹出,压入辅助栈中。则辅助栈的栈顶元素就是我们要弹出的元素,将其弹出即可。然后再将辅助栈中的元素全部弹出,压入主栈中。peek()
,可以用和pop()
操作类似的方式,得到最先压入栈的元素。empty()
,直接判断主栈是否为空即可。
时间复杂度分析
push()
:$O(1)$;pop()
: 每次需要将主栈元素全部弹出,再压入,所以需要 $O(n)$ 的时间;peek()
:类似于pop()
,需要 $O(n)$ 的时间;empty()
:$O(1)$;
C++ 代码
class MyQueue {
public:
/** Initialize your data structure here. */
stack<int> stk, cache;
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stk.push(x);
}
void copy(stack<int> &a, stack<int> &b) {
while (a.size()) {
b.push(a.top());
a.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
copy(stk, cache);
int res = cache.top();
cache.pop();
copy(cache, stk);
return res;
}
/** Get the front element. */
int peek() {
copy(stk, cache);
int res = cache.top();
copy(cache, stk);
return res;
}
/** Returns whether the queue is empty. */
bool empty() {
return stk.empty();
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* bool param_4 = obj.empty();
*/
我是栈1作为插入栈,栈2作为输出栈,栈2中有数据的时候需要peek或者pop直接对其操作就行,栈2为空的时候再把栈1中数据全部挪过来,这样写不用拷贝回去开销比较小,代码的话自我感觉写的和各位大佬比也比较简洁^^
这里好像没有考虑队列为空的情况
题目保证操作是有效的
请问copy函数中a.pop()是什么操作啊
弹出(删除)a的最顶部值。
题干中的MyQueue queue = new MyQueue();是不是有问题啊,我觉得是MyQueue *queue = new MyQueue();
牛
a.top是?
栈顶元素
这个程序为什么会报segmentation fault的错呀
在peek函数里也需要像pop函数那样判断一下s2是否为空。另外之后有问题尽量发在问答页面,这里是集中提问的地方,曝光度更大,会更及时得获得回复。
好的
那为啥yls的代码里没有判断是否为空啊
我的代码中所有元素一直都存在stk中,他的代码里不一定都存在s2中。
因为y总的代码在模拟出队列之前能保证所有的元素都在入的那个栈中,另外在出队列完成后,又copy回去,所有在出队列后也能保证
这里自己定义的pop函数 和stack的pop函数 重名,没问题吗 y总
pop是stack的成员函数,无影响。
前面是有queue.pop()或者stack.pop()有前缀,也相当于域作用限定符限制了
我们用两个栈来做,一个负责插入,一个负责读取。
可以的hh
哈哈哈大佬,这个需求好不好实现,感觉更好debug:https://www.acwing.com/problem/content/discussion/content/89/