题目一:
请设计一个栈,除pop与push方法,还支持min方法,可返回栈元素中的最小值。push、pop和min三个方法的时间复杂度必须为O(1)。
思路:题目要求时间复杂度为O(1),所以肯定不能用循环遍历的方式去解决,于是我们想到用空间换时间的方式去解决,如果我们已经维护好一个已经排好序的栈的话,那么min方法直接返回当前的栈顶元素就好了。于是我们可以定义另一个栈,然后用push方法和pop方法去维护这个栈。另一个栈的栈顶始终存的是在当前状态下最小的元素,如果再来一个数据小于另一个栈的栈顶,那么两个栈同时压入这个数。否则只是原栈压入,而另一个栈还是重复压入当前最小的数据。另外pop的时候两个栈需要同时弹出。
注意:代码中找不到的类前面的博客都有介绍,这里就没有重复写了。
1 import java.util.EmptyStackException; 2 3 public class StackWithMin extends DoubleLinkedList<Integer> implements IStack<Integer> { 4 @Override 5 public void push(Integer e) { 6 super.add(e); 7 if (brother.empty()) { 8 brother.push(e); 9 } else { 10 Integer peek = brother.peek(); 11 if (e < peek) { 12 brother.push(e); 13 } else { 14 brother.push(peek); 15 } 16 } 17 } 18 19 @Override 20 public Integer pop() { 21 if (size <= 0) 22 throw new EmptyStackException(); 23 ListNode<Integer> the = super.last.getPre(); 24 Integer res = the.getData(); 25 26 the.getPre().setNext(last); 27 last.setPre(the.getPre()); 28 the.setNext(null); 29 the.setPre(null); 30 size--; 31 brother.pop(); 32 return res; 33 } 34 35 @Override 36 public boolean empty() { 37 return getSize() == 0; 38 } 39 40 @Override 41 public int getSize() { 42 return super.getSize(); 43 } 44 45 @Override 46 public Integer peek() { 47 return last.getPre().getData(); 48 } 49 50 private MyStack<Integer> brother = new MyStack<>(); 51 52 public int min() throws Exception { 53 // ListNode<T> h = first.getNext(); 54 // int min = -1; 55 // while(h!=last){ 56 // if ((int)(h.getData())<min){ 57 // min = (int)(h.getData()); 58 // } 59 // } 60 // return min; 61 if (!brother.empty()) 62 return brother.peek(); 63 else 64 throw new Exception("没有元素了"); 65 } 66 67 public static void main(String[] args) throws Exception { 68 StackWithMin stack = new StackWithMin(); 69 stack.push(2); 70 stack.push(9); 71 stack.push(3); 72 stack.push(1); 73 stack.push(5); 74 75 System.out.println(stack.min()); // 输出1 76 } 77 }