力扣155. 最小栈(以空间换时间,使用辅助栈)
https://leetcode-cn.com/problems/min-stack/
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
示例:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路:
“以空间换时间”,使用辅助栈
入栈时,最小值入栈才同步;出栈时,最小值出栈才同步。
注意的点:
(1)辅助栈为空的时候,必须放入新进来的数;
(2)新来的数小于或者等于辅助栈栈顶元素的时候,才放入,特别注意这里“等于”要考虑进去,因为出栈的时候,连续的、相等的并且是最小值的元素要同步出栈;
(3)出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈。
复杂度分析:
时间复杂度:O(1),“出栈”、“入栈”、“查看栈顶元素”的操作不论数据规模多大,都只有有限个步骤,因此时间复杂度是:O(1)。
空间复杂度:O(N),这里 N 是读出的数据的个数。
//出栈时,最小值出栈才同步;入栈时,最小值入栈才同步。
#include "stdafx.h"
#include <vector>
#include <stack>
#include <iostream>
using namespace std;
class MinStack
{
private:
//数据栈
stack<int>data;
//辅助栈
stack<int>assist;
public:
//构造函数
MinStack()
{
cout << "构造函数成功" << '\n';
}
void push(int x)
{
data.push(x);
cout << "压栈成功,压入:" << x << '\n';
//辅助栈为空的时候,必须放入新进来的数
if (data.size() == 1)
{
assist.push(x);
cout << "压入最小值成功,压入:" << x << '\n';
}
//如果发现小于或者等于最小值的话,放进辅助栈
else
{
//这里“等于”要考虑进去,因为出栈的时候,连续的、相等的并且是最小值的元素要同步出栈;
if (x <= assist.top())
{
assist.push(x);
cout << "压入最小值成功,压入:" << x << '\n';
}
}
}
void pop()
{
if (data.top() != assist.top())
{
data.pop();
cout << "移除栈顶,移除:" << data.top() << '\n';
}
//如果出栈的是最小值,那么辅助栈的top也要出栈
//出栈的时候,辅助栈的栈顶元素等于数据栈的栈顶元素,才出栈。
else
{
data.pop();
assist.pop();
cout << "移除栈顶,同时移除最小值栈顶:" << data.top() << '\n';
}
}
int top()
{
cout << "栈顶:" << data.top() << '\n';
return data.top();
}
int getMin()
{
cout << "最小值:" << assist.top() << '\n';
return assist.top();
}
};
int main()
{
MinStack s;
s.push(-2);
s.push(0);
s.push(45);
s.push(-9);
s.push(0);
s.push(40);
s.pop();
s.pop();
s.pop();
s.pop();
s.pop();
auto result1 = s.top();
auto result2 = s.getMin();
return 0;
}