1、辅助栈实现
我现在需要实现一个栈,这个栈除了可以进行普通的push、pop操作以外,
还可以进行getMin的操作,getMin()获取当前栈的最小值。
使用辅助栈来存储最小值。如果当前要push的值比辅助栈的min值要小,那在辅助
栈push的值是最小值
总结:push和pop的时间复杂度都是O(1),空间是O(n)。
加与所给栈相同大小的栈实现:复杂度小但占空间
添加的栈只指示当前栈最小值
例:datastack minStack
4 2
2 2
8 7
7 7
public class MinStack {
private List<Integer> data = new ArrayList<Integer>();
private List<Integer> mins = new ArrayList<Integer>();
public void push(int num) {
data.add(num);
if (mins.size() == 0) {
// 初始化mins
mins.add(num);
} else {
// 辅助栈mins每次push当时最小值
int min = getMin();
if (num >= min) {
mins.add(min);
} else {
mins.add(num);
}
}
}
public int pop() {
// 栈空,异常,返回-1
if (data.size() == 0) {
return -1;
}
// pop时两栈同步pop
mins.remove(mins.size() - 1);
return data.remove(data.size() - 1);
}
public int getMin() {
// 栈空,异常,返回-1
if (mins.size() == 0) {
return -1;
}
// 返回mins栈顶元素
return mins.get(mins.size() - 1);
}
}
2、优化辅助栈
算法的空间优化:
上面的代码我们可以发现:data栈和mins栈的元素个数总是相等
的,mins栈中存储几乎都是最小的值(此部分是重复的!)
所以我们可以这样做:当push的时候,如果比min栈的值要小的,才放进mins
栈。同理,当pop的时候,如果pop的值是mins的最小值,mins才出栈,否则
mins不出栈!
如果一直push的值是最小值,那我们的mins辅助栈还是会有大量的重复元素,
此时我们可以使用索引(mins辅助栈存储的是最小值索引,非具体的值)
public class MinStack {
private List<Integer> data = new ArrayList<Integer>();
private List<Integer> mins = new ArrayList<Integer>();
public void push(int num) throws Exception {
data.add(num);
if(mins.size() == 0) {
// 初始化mins
mins.add(0);
} else {
// 辅助栈mins push最小值的索引
int min = getMin();
if (num < min) {
mins.add(data.size() - 1);
}
}
}
public int pop() throws Exception {
// 栈空,抛出异常
if(data.size() == 0) {
throw new Exception("栈为空");
}
// pop时先获取索引
int popIndex = data.size() - 1;
// 获取mins栈顶元素,它是最小值索引
int minIndex = mins.get(mins.size() - 1);
// 如果pop出去的索引就是最小值索引,mins才出栈
if(popIndex == minIndex) {
mins.remove(mins.size() - 1);
}
return data.remove(data.size() - 1);
}
public int getMin() throws Exception {
// 栈空,抛出异常
if(data.size() == 0) {
throw new Exception("栈为空");
}
// 获取mins栈顶元素,它是最小值索引
int minIndex = mins.get(mins.size() - 1);
return data.get(minIndex);
}
}
1895

被折叠的 条评论
为什么被折叠?



