包含main函数的栈问题知识点
设计一个支持 push、pop、top 等操作并且可以在 O(1) 时间内检索出最小元素的堆栈。
该问题要求的时间复杂度是在O(1)内。
如果直接使用一个int变量存储当前的最小值,我们的确可以获得最小值,但是当栈pop()了以后,我们无法获得次小值。我们需要一个数据结构来动态保存每个时刻的最小值,每当push()和pop()的时候,同样更新这个数据结构,而且时间复杂度也是O(1),那么看来需要额外O(n)的空间了。可以选择栈或者一个链表(实质上当作栈使用)。我们使用一个辅助栈来实现,该栈和主栈的大小相同,栈顶存放的是当前栈内的最小值。
即:
定义两个stack,一个为存放最小数的序列的辅助栈。
压栈时,先将元素 x 压入 stack1。然后判断 stack2 的情况:
stack2 栈为空或者栈顶元素大于 x,则将 x 压入 stack2 中。
stack2 栈不为空且栈定元素小于 x,则重复压入栈顶元素。
获取最小元素时,从 stack2 中获取栈顶元素即可。
代码实现:
import java.util.Stack;
public class MinStackDemo {
/**
* 压栈时,先将元素 x 压入 stack1。然后判断 stack2 的情况:
* stack2 栈为空或者栈顶元素大于 x,则将 x 压入 stack2 中。
* stack2 栈不为空且栈定元素小于 x,则重复压入栈顶元素。
* 获取最小元素时,从 stack2 中获取栈顶元素即可。
*/
private Stack<Integer> myStack1= new Stack<>();
private Stack<Integer> myStack2= new Stack<>();
//插入元素
public void push(int x){
myStack1.push(x);
if (myStack2.empty()||myStack2.peek()>x){
myStack2.push(x);
}else{
myStack2.push(myStack2.peek());
}
}
//弹出栈顶元素
public void pop(){
myStack1.pop();
myStack2.pop();
}
//取栈顶元素
public int top(){
return myStack1.peek();
}
//取最小值
public int min(){
return myStack2.peek();
}
}
public static void main(String[] args) {
MinStackDemo minStackDemo = new MinStackDemo();
minStackDemo.push(1);
minStackDemo.push(3);
minStackDemo.push(1);
minStackDemo.push(4);
minStackDemo.push(5);
minStackDemo.push(2);
minStackDemo.push(0);
minStackDemo.pop();
int top = minStackDemo.top();
int min = minStackDemo.min();
System.out.println("top="+top+",min="+min);
}
//结果:top=2,min=1
使用assert断言的方法进行逻辑判断的代码实现:
import java.util.Stack;
public class MinStackDemo{
Stack<Integer> myStack1 = new Stack<Integer>();
Stack<Integer> myStack2 = new Stack<Integer>();
public void push(int item){
myStack1.push(item);
if(myStack2.isEmpty()){
myStack2.push(item);
}else {
myStack2.push(myStack2.peek() < item ? myStack2.peek() : item);
}
}
public int pop(){
assert(myStack1.size()>0 && myStack2.size()>0);
myStack2.pop();
return myStack1.pop();
}
public int top(){
return myStack1.peek();
}
public int min(){
assert(myStack1.size()>0 && myStack2.size()>0);
return myStack2.peek();
}
}
上面两种写法:时间复杂度:O(1)、空间复杂度:O(n)。
后续如有更优的方法,会继续补充。