版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Abel_Liujinquan/article/details/89598513
今天在Leetcode刷了一道关于最小栈的问题,题目如下:
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
- push(x) – 将元素 x 推入栈中。
- pop() – 删除栈顶的元素。
- top() – 获取栈顶元素。
- getMin() – 检索栈中的最小元素。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
我的解法:
刚开始解这道题时,自己的想法是用一个数组实现栈,然后分别用属性length和属性tag记录栈顶下标,每次获取最小值都要执行一次for循环查找最小值,虽然提交通过了,但是所用时间和空间都比较大,于是在评论区找了一个比较优秀的解题方法,如下:
别人的优秀解法:
使用两个数组,一个作为数据存储栈,一个作为最小值栈(记录每次入栈后的最小值),代码如下:
class MinStack {
//以下是评论区比较好的解法,采用两个数组,一个作为数据栈,一个作为最小值栈
private Integer[]value; // 保存最小值数组
private Integer[]minValue; // 容量
private int capacity = 10;
private int size = 0; // 元素数量
public MinStack() {
value = new Integer[capacity];
minValue = new Integer[capacity];
}
// 将元素 x 推入栈中
public void push(int x) {
// 要扩容了
if (size >= capacity){
grow();
}
value[size] = x;
// 存最小值
if (size == 0){
minValue[size] = x;
} else if (minValue[size-1] > x){
minValue[size] = x;
} else {
minValue[size] = minValue[size-1];
}
size++;
}
// 删除栈顶的元素。
public void pop() {
value[--size] = null;
}
// 获取栈顶元素。
public int top() {
return value[size-1];
}
// 检索栈中的最小元素。
public int getMin() {
return minValue[size-1];
}
// 满了进行扩容,一倍
private void grow(){
capacity *= 1.5;
Integer []copy = new Integer[capacity];
Integer []minCopy = new Integer[capacity];
System.arraycopy(value, 0, copy, 0,size);
System.arraycopy(minValue, 0, minCopy, 0,size);
value = copy;
minValue = minCopy;
}
}
现在分析一下最小栈的存储过程和作用:
假如数据栈入栈的顺序是 -2,0,-3,数据栈和最小栈的栈顶指针 size 同步移动,最小栈变化如下:
增加一个最小值栈的作用:
每次入栈、出栈都更新最小值,如果数据栈出栈元素刚好是最小栈的栈顶元素,能够同步栈顶元素的位置,避免最小值出错。