**
Leetcode刷题 155题: 最小栈(基于python3和c++两种语言)
**
**
题目:
**
设计一个支持 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.
提示:
pop、top 和 getMin 操作总是在 非空栈 上调用。
**
c++程序的一种解法(简称:一解)
**
class MinStack {
public:
/** initialize your data structure here. */
stack<int> data, help; /*定义一个数据栈和一个辅助栈*/
MinStack() {
}
void push(int x) {
data.push(x);
//如果x是data和help的第一个元素,或者x小于等于help的最小元素,入栈
if(help.empty() || x <= help.top()) help.push(x);
//如果x大于help的最小元素,向help中再压入一遍该最小元素,保持两个栈元素个数相等
//比如data里现在有3,help里现在也有3,data里压入一个4,那么help里压入一个3
//这样如果把data的4弹出,我们同步把help的3也弹出
if(x > help.top()) help.push(help.top());
}
void pop() {
data.pop();
help.pop();
}
int top() {
return data.top();
}
int getMin() {
return help.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
**
**
结果:
**
c++程序的另一种解法(简称:二解):
class MinStack {
public:
/** initialize your data structure here. */
stack<int> data, help; /*定义一个数据栈和一个辅助栈*/
MinStack() {
}
void push(int x) {
data.push(x);
//如果x是data和help的第一个元素,或者x小于等于help的最小元素,入栈
if(help.empty() || x <= help.top()) help.push(x);
//如果x大于help的最小元素,向help中再压入一遍该最小元素,保持两个栈元素个数相等
//比如data里现在有3,help里现在也有3,data里压入一个4,那么help里压入一个3
//这样如果把data的4弹出,我们同步把help的3也弹出
//if(x > help.top()) help.push(help.top());
}
void pop() {
if(data.top() == help.top()){
help.pop();
}
data.pop();
}
int top() {
return data.top();
}
int getMin() {
return help.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
对比上面的两种c++程序,我们可以发现这两种编程的思想是不同的:
首先,我们来看下这两种解法的共同点,都是利用利用两个栈的思想来做的,即:一个主栈,一个辅助栈。主栈主要是存入需要存入的值,辅助栈主要是存入这些值的最小值的。
其次,我们再来看一下这两种解法的不同编程思想吧:一解和二解主要的不同是出现在push()和pop()的函数的编写上,一解主要是体现在push()上的,它每将一个值存入在主栈中,就要去判断一下该值是不是最小值,如果是最小值,则同样将该值压入辅助栈中的;如果发现压入主栈的值并不是该栈中的最小值,则将之前辅助栈中存入的最小值再压入一遍,这样始终保持主栈中的元素个数始终和辅助栈的元素个数是一样的。当主栈需要去弹栈的时候,对应的辅助栈也去弹栈,这样就能够始终去保持辅助栈的栈顶元素就是主栈中的最小值的。二解主要是体现在pop()上的,它每将一个值存入在主栈中,就要去判断一下该值是不是最小值,如果是最小值,则同样将该值压入辅助栈中的;如果发现压入主栈的值并不是该栈中的最小值,则辅助栈中不用压入任何元素,这样一来,主栈中的元素始终是大于等于辅助栈中的元素个数的,但是辅助栈中的栈顶元素值仍然是主栈中的最小值。当主栈需要去弹栈的时候,这个时候需要先去判断主栈弹出的元素值和辅助栈的栈顶元素是不是相等,如果相等,则需要主栈和辅助栈一块同时弹出的,否则只弹出主栈的栈顶元素,辅助栈不弹出元素。这样就能够始终去保持辅助栈的栈顶元素就是主栈中的最小值的。
总之,这两种编程思想虽然有所不同,但是同时都是基于两个栈的思想去得到栈中的最小值的,这样随便主栈中需要存入任何元素,都能很快利用辅助栈快速知道主栈中的最小值,大大提高效率。
python程序:
**
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
# 定义两个栈
self.stack = []
self.min_stack = []
def push(self, x: int) -> None:
self.stack.append(x)
if not self.min_stack or x <= self.min_stack[-1]: #表示如果self.min_stack为空或者x小于等于self.min_stack中的最后一个值
self.min_stack.append(x)
def pop(self) -> None:
if self.stack.pop() == self.min_stack[-1]:
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
**
结果:
**
``