最小栈
难度:
标签:
题目描述
设计一个支持 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.
提示:
-231 <= val <= 231 - 1
pop
、top
和getMin
操作总是在 非空栈 上调用push
,pop
,top
, andgetMin
最多被调用3 * 104
次
代码结果
运行时间: 34 ms, 内存: 19.4 MB
// Solution using Java Streams
/**
* MinStack class provides a stack with the ability to retrieve the minimum element in constant time.
*/
import java.util.*;
import java.util.stream.*;
public class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
/**
* Initializes the stack and the minStack.
*/
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
/**
* Pushes an element onto the stack.
* If the minStack is empty or the element is smaller than or equal to the top of minStack,
* push the element onto the minStack.
*
* @param val The value to push onto the stack.
*/
public void push(int val) {
stack.push(val);
if (minStack.isEmpty() || val <= minStack.peek()) {
minStack.push(val);
}
}
/**
* Removes the top element from the stack.
* If the element being removed is equal to the top of the minStack, pop the minStack as well.
*/
public void pop() {
if (stack.peek().equals(minStack.peek())) {
minStack.pop();
}
stack.pop();
}
/**
* Retrieves the top element of the stack.
*
* @return The top element of the stack.
*/
public int top() {
return stack.peek();
}
/**
* Retrieves the minimum element in the stack.
*
* @return The minimum element in the stack.
*/
public int getMin() {
return minStack.peek();
}
/**
* Retrieves all elements in the stack as a list.
*
* @return A list containing all elements in the stack.
*/
public List<Integer> getStackAsList() {
return stack.stream().collect(Collectors.toList());
}
}
解释
方法:
该题解使用两个栈来实现最小栈,一个栈 stack 存储所有元素,另一个栈 min_stack 存储当前的最小元素。在 push 操作时,如果新元素小于等于 min_stack 的栈顶元素,就将新元素也压入 min_stack。在 pop 操作时,如果弹出的元素等于 min_stack 的栈顶元素,就将 min_stack 的栈顶元素也弹出。这样可以保证 min_stack 的栈顶元素始终是当前 stack 中的最小元素。
时间复杂度:
O(1)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在设计最小栈时选择使用两个栈来实现,而不是使用一个栈配合其他数据结构如哈希表或优先队列?
▷🦆
在`pop`操作中,如果弹出的元素等于`min_stack`的栈顶元素时,为什么必须同时弹出`min_stack`的栈顶元素?
▷🦆
如果在`push`操作中,新压入的元素大于`min_stack`的栈顶元素,为什么选择不将其加入到`min_stack`?
▷🦆
请问`getMin`操作返回`min_stack`的栈顶元素为什么能保证是当前栈中的最小元素?
▷相关问题
滑动窗口最大值
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 输出:[3,3,5,5,6,7] 解释: 滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length