时间复杂度:输入数据大小为N时,算法运算所需花费的时间;
注意:在这里,指的并不是运行的绝对时间(受各种外界因素影响,如:cpu,网络等),而是指计算操作数量;
空间复杂度:通常指在输入数据大小为N时,算法运算所使用的【存储空间】+【输出空间】
存储空间:算法运行过程中,存储所有中间变量和对象等数据所需的空间大小;
输出空间:算法运行返回时,存储输出数据所需的空间大小;
第一题:剑指Offer 09.用两个栈实现队列(leetcode)
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
示例 1:
输入:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出:[null,null,3,-1,-1]
示例 2:
输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]
提示:
1 <= values <= 10000
最多会对 appendTail、deleteHead 进行 10000 次调用
首先需要了解一定栈与队列的知识:
栈:先进后出(坐电梯,先进电梯的,在同一层下电梯时,位置相对靠后,从而后出去)
队列:先进先出(可以理解为排队,先排队的先吃到)
关于栈的一些函数:
.empty() 判断是否为空,如果为空,返回1;
.push(" ") 将" "中间的值加入到栈的头部;
.pop() 删除栈的头部元素;
分析:
使用两个栈来实现队列;
栈与队列的区别在于,栈只能在尾部进行加入和删除,而队列在尾部增加,在头部删除;
因此难以实现的在于删除部分;
此处我们使用了两个栈,一个栈用于正序存储,一个用于倒叙存储;
倒叙存储的用于删除
正序存储的用于增加
这样子就可以保证删除以及增加的方向和队列是一致的;
class CQueue {
public:
//在这里_delete的_不可省略,否则会造成错误命名
stack<int> add,_delete;
CQueue() {}
void appendTail(int value) {
add.push(value);
}//对于加入队尾,直接加入即可
int deleteHead() {
//删除队列不为空,可以直接从队列中删除,即使中间有数据增加到add中,也不会影响到数据的相对删除顺序;
if(!_delete.empty()){
int tmp=_delete.top();
_delete.pop();
return tmp;
}
//所有栈为空,对应于队列为空,直接返回-1;
if(add.empty()){
return -1;
}
//add中有数据,而delete中无数据,而又需要进行删除操作
//此时需要反转,将add中的数全加载进入delete中
while(!add.empty()){
int tmp=add.top();
add.pop();
_delete.push(tmp);
}
int tmp=_delete.top();
_delete.pop();
return tmp;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/