每日一题算法MinStack:2020.05.12
class MinStack {
private static Stack<Integer> stack;
/** initialize your data structure here. */
public MinStack() {
stack=new Stack<Integer>();
}
public void push(int x) {
stack.push(x);
}
public void pop() {
stack.pop();
}
public int top() {
return stack.get(stack.size()-1);
}
public int getMin() {
int index=0;
int min=stack.get(0);
for (int i=0;i<stack.size();i++){
if (stack.get(i)<min){
min=stack.get(i);
index=i;
}
}
return stack.get(index);
}
}
初次版本
成功,但是并不是最好的办法
可以看出,这种方法明显不够优秀,现在想一想,从空间复杂度或者时间复杂度上如何去优化。
空间复杂度,不使用系统给的栈,因为这个栈是实现了list接口的,能不能用数组实现一个栈呢?答案是肯定的,但是实际上会非常复杂,数组会便于查找最小数但是不适合入栈和出栈,但是从空间复杂度上来说是最小的。
试着用数组实现一个栈。
发现问题!
经过思考后发现,如果一个数组长度为10,需要压入一个进栈时,需要再创建一个长度增加一个的数组,这样相当于复制了一个数组,也许可以通过StringBuilder的扩容方式来扩展数组,给数组设定一个实际的长度,如果超过了这个大小,那么长度翻倍,然后数组的后方有许多的空位。这样可以节省很多扩容的时间。
栈大小的初始大小就设置为16,因为StringBuilder设置的就是16,这么设置肯定是有道理的。
所以,如果要用数组来实现栈的话,肯定需要2个变量,一个表示栈顶的位置,一个表示最小值,栈的实际大小不需要变量,因为可以直接通过数组的长度获得。
实现之后发现了leecode的一个bug,输的好冤。
class MinStack {
private static int[] stack;
private static int min=Integer.MAX_VALUE;
private static int topIndex;
public MinStack(){
stack=new int[16];
}
public void push(int x){
if (x<min)
min=x;
if (topIndex+1>=stack.length)
remake();
topIndex++;
stack[topIndex]=x;
}
public void pop(){
if (stack[topIndex]==min)
findMin();
topIndex--;
}
public int top(){
return stack[topIndex];
}
public int getMin(){
return min;
}
public void remake(){
int[] newstack=new int[stack.length*2];
for (int i=0;i<stack.length;i++){
newstack[i]=stack[i];
}
stack=newstack;
}
public void findMin(){
min=stack[0];
for (int i=0;i<topIndex-1;i++){
if (stack[i]<=min)
min=stack[i];
}
}
}
结果不知道是不是正确的,因为存在bug,没能完成验证
找到了bug所在,在leecode里写算法千万不要用静态全局变量!!!
出现错误
错误出现的位置,栈中的第2个0弹出时,最小值还是0.
经过调试,发现是由于设置的初始栈顶位置下标为0,而在插入之前会将下标+1,所以实际上第一个值的位置是在下标1的位置。
修改方式,初始栈顶位置下标改为-1或者在插入之后修改栈顶的位置。
出现错误
错误原因分析,在所有元素出栈时没有将最小值标记重置,导致新值入栈时显示的最小值不是新的最小值(比之前的最小值大)。
修改方式:在栈顶下标为0时出栈操作会将最小值重置为最大整数。
if(topIndex==0)
min=Integer.MAX_VALUE;
else {
min=stack[0];
for (int i=0;i<=topIndex-1;i++){
if (stack[i]<=min)
min=stack[i];
}
}
}
通过,本以为自己写的数据结构会更加节省内存,没想到没有实现。