双栈算法(一)
1、设计一个有getMin功能的栈,除了实现栈基本的功能外,再实现返回栈中最小元素的操作。
- pop,push,getMin操作的时间复杂度均为O(1)
- 可使用现成的栈结构
思想:在实现时使用两个栈,一个栈记录当前的数据,另一个栈保存当前的最小值。有两种实现方式,现实现第一种:
(1)压入数据规则:
新元素为newData,先将newData压入data栈中,然后进行判断,如果min栈也为空,则将newData压入min栈中。如果不为空,比较newData和min栈的栈顶元素的大小,如果newData <= min.top(), 则将newData压入min栈中,否则不进行操作。
(2)弹出数据规则:
先弹出data栈的栈顶元素,记为value,然后与min栈的栈顶元素进行比较,如果value == min.top(), min栈弹出栈顶元素;当value > min.top()时,返回value。
不难得出min栈中的元素是从栈底到栈顶逐渐变小的,min栈栈顶的元素是min栈的最小值,也是当前data栈的最小值,所以value值只可能>=min.top()
(3)查询当前栈中最小值
直接返回min栈的栈顶元素,当为空时直接推出。
代码:
class mystack
{
public:
mystack() {
cout << "mystack()" << endl;
}
~mystack() {
cout << "~mystack()" << endl;
}
int getMinData() const {
if (stackMin.empty()) {
cout << "your stackMin is empty" << endl;
return 0;
}
return stackMin.top();
}
void push(const int newData) {
stackData.push(newData);
if (stackMin.empty()) {
stackMin.push(newData);
}
else {
auto temp = stackMin.top();
if (newData <= temp) {
stackMin.push(newData);
}
}
}
int pop() {
auto temp = stackData.top();
stackData.pop();
if (temp == stackMin.top()) {
stackMin.pop();
return temp;
}
if (temp > stackMin.top()) {
return temp;
}
}
private:
stack<int> stackData;
stack<int> stackMin;
};
2、通过两个栈实现队列
思想:定义两个栈stPush, stPop,压入数据时只往stPush中压入,弹出数据时只从stPop中弹出,这样就能实现类似队列的功能。但是有两个注意事项:
- 如果要从stPush往stPop中压入数据,必须一次性把所有数据全部压入。
- 如果stPop不为空,则不能向其中压入数据。
代码:
class stackQueue {
public:
stackQueue() { cout << "stackQueue()" << endl; }
~stackQueue() { cout << "~stackQueue()" << endl; }
void add(const int newNum) {
stPush.push(newNum);
if (stPop.empty()) { pushToPop(); }
}
int pop() {
if (stPush.empty() && stPop.empty()) {
cout << "stackQueue is empty" << endl;
return -1;
}
pushToPop();
auto temp = stPop.top();
stPop.pop();
return temp;
}
int front() {
if (stPush.empty() && stPop.empty()) {
cout << "stackQueue is empty" << endl;
return -1;
}
pushToPop();
return stPop.top();
}
private:
stack<int> stPush;
stack<int> stPop;
void pushToPop() {
if (stPop.empty()) {
while (!stPush.empty()) {
auto temp = stPush.top();
stPop.push(temp);
stPush.pop();
}
}
}
};