返回
用栈优雅地实现 LeetCode 155:最小栈
前端
2024-02-08 03:51:12
在编程的世界里,栈是一种基础而强大的数据结构,它以其后进先出 (LIFO) 的特性而闻名。在 LeetCode 155 中,我们面临着一项富有挑战性的任务:设计一个栈,它不仅可以执行基本的栈操作(push、pop、top),还能在常数时间内检索到栈中的最小元素。
拥抱优雅的解决方案
要解决这个问题,我们需要超越传统栈的范畴,探索更精妙的解决方案。让我们用两个栈来实现这个最小栈:
- 主栈: 它将按 LIFO 顺序存储元素。
- 辅助栈: 它将按递增顺序存储主栈中的最小元素。
每次向主栈添加一个元素时,我们也将其添加到辅助栈中,前提是该元素小于或等于辅助栈的栈顶元素。当我们从主栈中弹出元素时,如果该元素等于辅助栈的栈顶元素,我们也从辅助栈中弹出该元素。
这种设计确保了辅助栈的栈顶元素始终是主栈中的最小元素。因此,检索最小元素只需查看辅助栈的栈顶即可。
实现细节:
JavaScript:
class MinStack {
constructor() {
this.stack = [];
this.minStack = [];
}
push(val) {
this.stack.push(val);
if (this.minStack.length === 0 || val <= this.minStack[this.minStack.length - 1]) {
this.minStack.push(val);
}
}
pop() {
if (this.stack.length === 0) return null;
const val = this.stack.pop();
if (val === this.minStack[this.minStack.length - 1]) {
this.minStack.pop();
}
return val;
}
top() {
return this.stack[this.stack.length - 1];
}
min() {
return this.minStack[this.minStack.length - 1];
}
}
Python:
class MinStack:
def __init__(self):
self.stack = []
self.min_stack = []
def push(self, val):
self.stack.append(val)
if not self.min_stack or val <= self.min_stack[-1]:
self.min_stack.append(val)
def pop(self):
if not self.stack: return None
val = self.stack.pop()
if val == self.min_stack[-1]:
self.min_stack.pop()
return val
def top(self):
return self.stack[-1] if self.stack else None
def min(self):
return self.min_stack[-1] if self.min_stack else None
Java:
import java.util.Stack;
public class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
if (minStack.isEmpty() || val <= minStack.peek()) {
minStack.push(val);
}
}
public int pop() {
if (stack.isEmpty()) return -1;
int val = stack.pop();
if (val == minStack.peek()) {
minStack.pop();
}
return val;
}
public int top() {
return stack.peek();
}
public int min() {
return minStack.peek();
}
}
C++:
#include <stack>
class MinStack {
private:
stack<int> stack;
stack<int> minStack;
public:
void push(int val) {
stack.push(val);
if (minStack.empty() || val <= minStack.top()) {
minStack.push(val);
}
}
int pop() {
if (stack.empty()) return -1;
int val = stack.top();
stack.pop();
if (val == minStack.top()) {
minStack.pop();
}
return val;
}
int top() {
return stack.top();
}
int min() {
return minStack.top();
}
};
优雅与效率的融合
这种双栈方法巧妙地将 LIFO 的便利性与快速检索最小元素的能力结合在一起。时间复杂度保持在 O(1) 的常数级别,从而确保了效率。
结论
通过超越传统栈的局限,我们创造了一个优雅而高效的解决方案,使 LeetCode 155 中的最小栈问题迎刃而解。这个双栈方法彰显了数据结构的创造性和适应性,展示了技术创新的力量。