剑指Offer 30:含min函数的栈
2023-10-18 12:22:03
引言
栈是一种重要的数据结构,它遵循后进先出的原则,即最后进栈的元素最先出栈。在许多计算机科学问题和算法中,栈都被广泛应用。
剑指Offer第30题「包含min函数的栈」是一个经典的栈问题,它要求我们设计一个栈,除了具有基本的栈操作(如压栈、出栈和取栈顶元素)外,还能够在O(1)的时间复杂度内返回栈中的最小元素。
问题分析
为了解决这个问题,我们需要仔细分析问题的要求。首先,我们需要维护一个栈,以便能够执行基本的栈操作。其次,我们需要一种方法来跟踪栈中的最小元素,以便能够在O(1)的时间复杂度内返回它。
解决方案
有两种主要的方法可以解决这个问题:
-
使用辅助栈 :我们可以使用一个辅助栈来存储栈中的最小元素。当我们将一个元素压入栈时,我们将其与辅助栈中的最小元素进行比较,并将较小的元素压入辅助栈。当我们从栈中弹出元素时,我们也从辅助栈中弹出相应的最小元素。这样,辅助栈始终包含栈中的最小元素,并且我们可以通过访问辅助栈的栈顶元素来获取它。
-
使用一个变量存储最小值 :另一种方法是使用一个变量来存储栈中的最小值。当我们将一个元素压入栈时,我们将其与当前的最小值进行比较,并将较小的元素存储在变量中。当我们从栈中弹出元素时,我们检查变量中的值是否等于弹出元素,如果是,则更新变量中的值。这样,变量中的值始终包含栈中的最小元素,并且我们可以通过访问变量来获取它。
代码实现
以下是用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 x) {
stack.push(x);
if (minStack.isEmpty() || x <= minStack.peek()) {
minStack.push(x);
}
}
public int pop() {
int x = stack.pop();
if (x == minStack.peek()) {
minStack.pop();
}
return x;
}
public int getMin() {
return minStack.peek();
}
}
import java.util.Stack;
public class MinStack {
private Stack<Integer> stack;
private int min;
public MinStack() {
stack = new Stack<>();
min = Integer.MAX_VALUE;
}
public void push(int x) {
stack.push(x);
if (x < min) {
min = x;
}
}
public int pop() {
int x = stack.pop();
if (x == min) {
min = Integer.MAX_VALUE;
for (int i : stack) {
if (i < min) {
min = i;
}
}
}
return x;
}
public int getMin() {
return min;
}
}
复杂度分析
对于第一种解决方案,每次压栈和出栈的时间复杂度都是O(1),返回最小值的时间复杂度也是O(1)。
对于第二种解决方案,压栈和出栈的时间复杂度都是O(1),返回最小值的时间复杂度最坏情况下是O(n),但在大多数情况下是O(1)。
总结
在本文中,我们介绍了剑指Offer第30题「包含min函数的栈」的两种解决方案。第一种解决方案使用辅助栈来存储栈中的最小元素,而第二种解决方案使用一个变量来存储栈中的最小值。这两种解决方案都有各自的优缺点,开发者可以根据自己的需要选择适合自己的解决方案。