这题大体思路比较简单,因为时间复杂度要求是常数级别,因此不能用简单遍历的方法,但空间复杂度没有要求,因此可以借助辅助栈的形式。
import java.util.Stack;
public class MinStack {
// 定义两个栈:stack用于存储所有元素,minStack用于存储当前栈的最小值
private Stack<Integer> stack;
private Stack<Integer> minStack;
// 构造函数初始化两个栈
public MinStack() {
stack = new Stack<Integer>();
minStack = new Stack<Integer>();
}
public void push(int val) {
stack.push(val);
// 如果minStack为空,或者新加入的值小于等于minStack的顶部元素,将其加入minStack
if (minStack.isEmpty() || val <= minStack.peek()) {
minStack.push(val);
}
}
public void pop() {
// 如果stack的顶部元素等于minStack的顶部元素,同时从两个栈中弹出
if (stack.peek().equals(minStack.peek())) {
minStack.pop();
}
stack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
但自己写题的过程中,出现了一些报错。
- java.lang.NullPointerException: Cannot invoke "java.util.Stack.push(Object)" because "this.stack" is null
错误发生是因为你试图在一个尚未初始化的Stack
对象上调用push
方法。在 Java 中,如果你声明了一个对象引用但没有用new
关键字为其分配内存(即没有初始化它),那么这个引用默认值是null
。试图调用一个null
引用的任何方法都会导致NullPointerException
。
- 成员变量的定义:
stack
和minStack
应该作为类的成员变量,而不是在构造函数中重新定义,这样它们才能在各个方法中被访问。
这里,class MinStack { Stack <Integer> stack; Stack <Integer> minStack; }
stack
和minStack
被声明为Stack<Integer>
类型的变量,但是它们目前指向null
。
public MinStack() { stack = new Stack<Integer>(); minStack = new Stack<Integer>(); }
在 MinStack
的构造函数中,使用 new Stack<Integer>();
创建了两个新的 Stack<Integer>
对象。new
关键字确保每次调用都会创建一个新的对象。这些新创建的对象分别被赋值给 stack
和 minStack
变量,因此这两个引用变量现在指向了实际的对象,而不再是 null。
一旦 stack
和 minStack
被初始化并指向了实际的 Stack
对象,你就可以安全地调用 Stack
类的方法了,比如 push()
, pop()
, peek()
, 等等,而不会遇到 NullPointerException
。