每日一题,防止痴呆 = =
一、题目大意
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof
二、题目思路以及AC代码
思路:
这道题我一开始看到的时候第一思路是这样的:因为让用两个栈来实现队列,我们只需要一个栈来存储元素,另一个栈在输出时用来颠倒一下就可以了,我觉得这也是最暴力的办法了,然后时间花费的有一些多,我就考虑如何更简便的去做。
上面的做法是每次在输出元素的时候,都要对存储数据的栈做一次颠倒,这着实没有什么必要,因为我们如果先连续的向队列里push,再连续的从队列里取出,其实我们只要颠倒一次,然后不断的从颠倒的栈中取出即可,这样我们可以针对连续push和连续pop的情况进行优化,即我们只在push和pop操作交替的时候,才进行颠倒的操作,这样应该就可以减少很多时间消耗,结果表明,确实效果更好的一些,但还不是很明显。
然后我参考了一下速度快一些的代码的思路,他们和我一样是使用两个数组,一个用来append,一个用来delete,但是在append的时候不做操作,直接append到第一个栈中,然后在输出元素,也就是delete的时候,如果第二个栈不为空,则直接delete,如果为空,那么把第一个栈中的元素颠倒顺序保存到第二个栈中,继续。这种方法看起来好像是包含了上面的优化方法的。
AC代码
最暴力:
class CQueue {
private:
stack<int> content;
public:
CQueue() {
}
void appendTail(int value) {
content.push(value);
}
int deleteHead() {
if (content.empty()) return -1;
stack<int> temp;
while (!content.empty()) {
temp.push(content.top()); content.pop();
}
int res = temp.top(); temp.pop();
while (!temp.empty()) {
content.push(temp.top()); temp.pop();
}
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
只在操作交替时颠倒:
class CQueue {
private:
stack<int> append_stack;
stack<int> delete_stack;
bool appending;
public:
CQueue() {
appending = true;
}
void appendTail(int value) {
if (!appending) {
// while (!append_stack.empty()) append_stack.pop();
appending = true;
while(!delete_stack.empty()) {
append_stack.push(delete_stack.top()); delete_stack.pop();
}
}
append_stack.push(value);
}
int deleteHead() {
if (appending) {
// while (!delete_stack.empty()) delete_stack.pop();
appending = false;
while (!append_stack.empty()) {
delete_stack.push(append_stack.top()); append_stack.pop();
}
}
if (delete_stack.empty()) return -1;
int res = delete_stack.top(); delete_stack.pop();
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
只在需要时颠倒:
class CQueue {
private:
stack<int> append_stack;
stack<int> delete_stack;
public:
CQueue() {
}
void appendTail(int value) {
append_stack.push(value);
}
int deleteHead() {
int res = -1;
if (!delete_stack.empty()) {
res = delete_stack.top(); delete_stack.pop();
return res;
}
while (!append_stack.empty()) {
delete_stack.push(append_stack.top()); append_stack.pop();
}
if (!delete_stack.empty()) {
res = delete_stack.top(); delete_stack.pop();
}
return res;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
如果有问题,欢迎大家指正!!!