42 用两个栈实现队列
思想很简单,很容易想到,当要pop的时候将栈1的内容全部pop到栈2中,但是这样存在一个问题:当连续push的数量和连续pop的数量不一致的时候就会出现问题,比如:push1,push2,pop,push3,pop,pop,正确的应该是
1,2,3,但是这种做法就会变成是1,3,2.其实改正很简单,只要判断栈2是否为空,如果为空再push新元素,否则就直接pop!!!
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
43. 包含min函数的栈![](https://img-blog.csdnimg.cn/7f18ef6bbae44af1bc939a4697a01674.png)
思路很简单,另开一个list维护最小值,但是用sort排序时间复杂度O(NlogN).
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
Stack<Integer> s = new Stack<>();
ArrayList<Integer> list = new ArrayList<>();
public void push(int node) {
s.push(node);
list.add(node);
}
public void pop() {
s.pop();
list.remove(list.size()-1);
}
public int top() {
int tmp = s.pop();
s.push(tmp);
return tmp;
}
public int min() {
ArrayList<Integer> list2= (ArrayList<Integer>)list.clone();
list2.sort((a,b)->a-b);
return list2.get(0);
}
}
注意这里要另开一个数组,原地sort的话,下一次pop的元素就不是原来栈的第一个。另外list的复制不能直接用等号,这样只是把指针给新变量,原数组没有边,可以用clone函数
看了题解有时间复杂度O(1)的思路:
另外开一个存最小值的栈,和原栈一一对应
import java.util.Stack;
public class Solution {
Stack<Integer> s = new Stack<>();
Stack<Integer> mins = new Stack<>();
//int min = Integer.MAX_VALUE;
public void push(int node) {
s.push(node);
if(mins.isEmpty()||mins.peek()>node){
mins.push(node);//正确做法为每次判断如果新来的不是更小的,就push上一次的,因为最小值栈每次存的就是目前为止在栈中的最小
}else
mins.push(mins.peek());
//if(node<min) min=node;
//mins.push(min); 这样是不行的!!!!!
}
public void pop() {
s.pop();
mins.pop();
}
public int top() {
return s.peek();
}
public int min() {
return mins.peek();
}
}
注意注释掉的方法是不行的,不能存一个全局最小的来判断,因为有可能最小的被pop出去了,比如push 1, 2 -1对应的最小值栈为1 1 -1,然后pop之后再push3,上面这种做法最小值栈pop-1之后新的还是会push-1,因为min是全局最小。