本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
155. 最小栈
来源:力扣(LeetCode)
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack()初始化堆栈对象。void push(int val)将元素val推入堆栈。void pop()删除堆栈顶部的元素。int top()获取堆栈顶部的元素。int getMin()获取堆栈中的最小元素。
示例 1:
输入:
["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.
提示:
- <= val <=
- pop、top 和 getMin 操作总是在 非空栈 上调用
- push, pop, top, and getMin最多被调用 次
解法
对于这类题目一般是使用辅助栈,类似的题目有用两个栈实现队列,只用队列实现栈,顺序倒一遍,都是需要使用辅助栈或者队列;
- 辅助栈:一个栈正常放元素,一个辅助栈放最小元素,每次新元素都与辅助栈栈顶元素进行比较,如果小于该栈顶,则入栈;如果大于该栈顶,则将栈顶元素复制一遍;
- 链表结构体:栈是需要连续数组的,链表是可以有多重属性的,也能保持前后位置关系;适用一个单链表结构题,属性有该节点的值,该节点的最小值,该节点的下一个节点;由于栈是先入后出,那么后入的节点的下一节点就是之前的节点;
代码实现
辅助栈
python实现
class MinStack:
def __init__(self):
self.data = []
self.helper = []
def push(self, val: int) -> None:
self.data.append(val)
if len(self.helper) == 0 or val <= self.helper[-1]:
self.helper.append(val)
else:
self.helper.append(self.helper[-1])
def pop(self) -> None:
if self.data:
self.helper.pop()
self.data.pop()
def top(self) -> int:
return self.data[-1] if self.data else -1
def getMin(self) -> int:
return self.helper[-1] if self.helper else -1
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
c++实现
class MinStack {
vector <int> data;
vector <int> helper;
public:
MinStack() {
}
void push(int val) {
data.push_back(val);
if (helper.empty() || helper.back() > val)
helper.push_back(val);
else
helper.push_back(helper.back());
}
void pop() {
if (!data.empty()) {
data.pop_back();
helper.pop_back();
}
}
int top() {
return !data.empty() ? data.back() : -1;
}
int getMin() {
return !helper.empty() ? helper.back() : -1;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
复杂度分析
- 时间复杂度:
- 空间复杂度:
链表结构
python实现
class ListNode:
def __init__(self, val=None, min_val=None, next_node=None):
self.val = val
self.min = min_val
self.next = next_node
class MinStack:
def __init__(self):
self.node = ListNode()
def push(self, val: int) -> None:
if not self.node or self.node.val == None: # 进行node判断,是否为None(原因是pop可能到最后节点为None,或者是初始化的节点)
self.node = ListNode(val, val)
else:
self.node = ListNode(val, min(self.node.min, val), self.node)
def pop(self) -> None:
self.node = self.node.next
def top(self) -> int:
return self.node.val
def getMin(self) -> int:
return self.node.min
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(val)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
c++实现
class MinStack {
public:
struct Node {
int val, mn;
Node* next;
Node(int _val, int _min, Node* _next=NULL) {
val = _val;
mn = _min;
next = _next;
}
} *head;
void push(int val) {
if (!head)
head = new Node(val, val);
else
head = new Node(val, min(val, head->mn), head);
}
void pop() {
if (!head) return;
Node* tmp = head;
head = head->next;
delete(tmp);
}
int top() {
if(!head) return -1;
return head->val;
}
int getMin() {
if(!head) return -1;
return head->mn;
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
复杂度分析
- 时间复杂度:
- 空间复杂度: