给栈结构设计一个求最小值的操作,要求入栈、出栈以及求最小值均在O(1)完成。
思路:
黑盒:作为一个整体的栈结构,作为黑盒,只有push,pop操作接口,并且提供求取最小值的接口。
白盒:细窥上述黑盒内部结构,内部由两个辅助栈最小栈
辅助栈
来完成,实现接口细节如下:
- push:当我们压入栈元素时,要保持栈内“排序”,从而达到能获取最小值。压入的元素与
最小栈
栈顶元素相比,如果小于则压入最小栈
,否则压入辅助栈
。 - pop:优先从
辅助栈
弹出,弹出前比较最小栈
栈顶,若相等,则一起弹出
求最小值:
- 直接返回
最小栈
的栈顶元素即可,该元素即为当前数据栈
中的最小值。
代码:
#include <stack>
#include <iostream>
using namespace std;
class MinStack {
private:
stack<int> dataStack;
stack<int> minStack;
public:
MinStack() {}
void push(int x) {
dataStack.push(x);
if (minStack.empty() || x <= minStack.top()) {
minStack.push(x);
}
}
void pop() {
if (!dataStack.empty()) {
if (dataStack.top() == minStack.top()) {
minStack.pop();
}
dataStack.pop();
}
}
int top() {
if (!dataStack.empty()) {
return dataStack.top();
}
return -1; // 栈为空时返回-1
}
int getMin() {
if (!minStack.empty()) {
return minStack.top();
}
return -1; // 栈为空时返回-1
}
};
int main() {
MinStack minStack;
minStack.push(3);
minStack.push(5);
cout << "Min: " << minStack.getMin() << endl; // 输出:Min: 3
minStack.push(2);
cout << "Min: " << minStack.getMin() << endl; // 输出:Min: 2
minStack.pop();
cout << "Top: " << minStack.top() << endl; // 输出:Top: 5
cout << "Min: " << minStack.getMin() << endl; // 输出:Min: 3
return 0;
}
给出策略利用栈去完成一个序列的排序,并分析相应的性能。
思路:
需要排序栈
来辅助完成,每次要压入栈时,要找到适合他的位置!
- 当前数小于栈顶,则直接压入。
- 当前数大于栈顶,则需要pop栈,直到栈顶大于当前数,压入后,将之前pop出的元素压回(找到他合适的位置)
pop出的元素存在哪里?
新开数组?占空间✖
压回原栈,记录个数,最后的时候再全部pop()✅
代码
#include <stack>
#include <vector>
#include <iostream>
using namespace std;
void sortStack(stack<int>& input) {
stack<int> tempStack;
while (!input.empty()) {
int temp = input.top();
input.pop();
// 找到合适位置插入元素
while (!tempStack.empty() && tempStack.top() > temp) {
input.push(tempStack.top());
tempStack.pop();
}
tempStack.push(temp);
}
// 将排序后的元素转移到原栈中
while (!tempStack.empty()) {
input.push(tempStack.top());
tempStack.pop();
}
}
int main() {
stack<int> myStack;
vector<int> input = {5, 2, 7, 3, 1};
// 将输入序列压入栈中
for (int num : input) {
myStack.push(num);
}
// 排序栈
sortStack(myStack);
// 打印排序后的栈
cout << "Sorted Stack: ";
while (!myStack.empty()) {
cout << myStack.top() << " ";
myStack.pop();
}
cout << endl;
return 0;
}