目录
题目
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
提示:
- 各函数的调用总次数不超过 20000 次
解题思路
分析一下题目,很中规中矩的一道题,push入栈和pop出栈的操作和普通栈的操作一样,唯一需要注意的是min返回当前栈帧中最小值的操作,因为需要其时间复杂度为常数阶,这也就限制了不能使用查找算法来返回最小值而只能以直接返回最小值的方式进行。
此时便需要一个数组,模拟栈帧、一个数组,存放所有栈帧情况下的最小值,方便回溯、一个指针,指向当前栈帧顶部的有效元素。
- stack,int类型数组,最大长度为20000。
- MinArray,int类型数组,最大长度为20000。
- top,int类型变量,初始值为-1。
既然无法使用查找算法查找当前栈帧的最小值,那么便只能每次入栈都将当前栈帧中的最小值保存下来,而且还不能仅使用一个变量来保存最小值,因为每进行一次入栈/出栈操作,当前栈帧的最小值都会改变,因此最小值的存放必须具有回溯功能。因此就可以定义一个数组,与栈帧共用一个指针,在栈帧改变时同步改变数组。
由于存放的是每次入栈/出栈后栈帧的最小值,那么当第一个元素入栈时,栈帧中的最小值就是当前入栈的元素;之后的每一个元素入栈时,由于数组每次存放的是当时栈帧的最小值,那么便只需要将当前入栈的元素值与前一时刻栈帧的最小值进行比较,便可以确定当前栈帧的最小值。
由于栈帧和数组是同步改变的,因此指针指向的位置就是当前栈帧中顶部的有效元素以及当前栈帧中的最小值。
题解
class MinStack {
int[] stack = new int[20000]; //定义栈
int[] MinArray = new int[20000]; //存放每次的最小值,方便回溯
int top;
/** initialize your data structure here. */
public MinStack() {
top = -1; //永远指向当前栈帧的位置(有效元素位置)
}
public void push(int x) {
stack[++top] = x; //元素入栈
//存放当前栈帧中的最小值
if(top == 0){ //如果栈帧中只有一个元素,那么最小值就是这个元素
MinArray[top] = x;
}else{ //如果栈帧中的元素多余一个,那么只需要和之前栈帧的最小值比较就行
MinArray[top] = x < MinArray[top - 1] ? x : MinArray[top - 1];
}
}
public void pop() {
--top;
}
public int top() {
return stack[top];
}
public int min() {
return MinArray[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.min();
*/