题意整理
实现一个返回最小值的时间复杂度为的栈。正常情况下,栈的push,pop操作都为
,但是返回最小值,需要遍历整个栈,时间复杂度为
。
思路
最开始看见题的第一反应是用一个中间变量暂存栈内最小值,但细想一下就会发现只用一个中间量暂存最小值的话,在出栈时最小值有可能被弹出从而需要再去找栈内最小值,算法更复杂,因此想到用空间换时间:用另一个栈存储压栈过程中每一次压栈时对应的最小值,主栈出栈时,最小栈同步出栈,min()直接返回最小栈栈顶元素。
具体做法
增加一个最小栈,用空间换时间,在实现时有两种细节有些微差异的方法。
方法一
最小栈只在栈为空或入栈元素小于等于栈顶时压栈,出栈时判断主栈栈顶与最小栈栈顶元素是否相等,相等则同步出栈。
示例:
主栈S依次入栈:-1,2,1,-2,4,-3
最小栈依次入栈:-1,跳,跳,-2,跳,-3
图解:
代码:
class Solution { private: stack<int> S; stack<int> Min; public: void push(int value) { S.push(value); if(Min.empty() || value <= Min.top()){ //如果最小栈为空或栈顶值小于等于value,value入栈最小栈 Min.push(value); } } void pop() { if(Min.top() == S.top()) //若最小栈栈顶元素等于主栈顶元素,最小栈也弹出栈顶 Min.pop(); S.pop(); } int top() { return S.top(); } int min() { return Min.top(); } };
复杂度分析
时间复杂度:入栈、出栈以及min都为
空间复杂度:需要有辅助栈,与输入序列有关,最好为 ,最差为
方法二
最小栈如主栈同步压栈,但当压栈元素大于最小栈栈顶时,最小栈压栈自身栈顶元素,出栈时最小栈与主栈同步出栈。
示例:
主栈S依次入栈-1,2,1,-2,4,-3
最小栈依次入栈:-1,-1,-1,-2,-2,-3
图解:
代码:
class Solution { private: stack<int> S; stack<int> Min; public: void push(int value) { S.push(value); if(Min.empty() || value <= Min.top()){ //如果最小栈为空或栈顶值小于等于value,value入栈最小栈 Min.push(value); } else Min.push(Min.top()); //否则入栈栈顶元素 } void pop() { Min.pop(); //最小栈和主栈同步弹出栈顶元素 S.pop(); } int top() { return S.top(); } int min() { return Min.top(); } };
复杂度分析
时间复杂度:入栈、出栈以及min都为
空间复杂度:需要有辅助栈,入栈出栈与主栈同步,复杂度为