public boolean isValid(String s) { Deque<Character> deque = new LinkedList<>(); Map<Character, Character> map = new HashMap<>(3); map.put(')', '('); map.put('}', '{'); map.put(']', '['); for (int i=0; i<s.length(); i++) { char c = s.charAt(i); if (!map.containsKey(c)) { deque.addFirst(c); }else { if (deque.isEmpty() || deque.peek()!=map.get(c)) return false; deque.removeFirst(); } } return deque.isEmpty(); }
栈:先进先出。最小栈:每个节点保留最小值;
class MinStack { private Node first; private int N; private class Node { private int val; private int min; private Node next; public Node(int val, int min) { this.val = val; this.min = min; } } public MinStack() { } public int size() { return N; } public boolean isEmpty() { return size()==0; } public void push(int val) { if (isEmpty()) { first = new Node(val, val); }else { Node oldFirst = first; first = new Node(val, Math.min(val, first.min)); first.next = oldFirst; } N++; } public void pop() { if (isEmpty()) return; first = first.next; N--; } public int top() { if (isEmpty()) throw new RuntimeException("None item"); return first.val; } public int getMin() { if (isEmpty()) throw new RuntimeException("None item"); return first.min; } }
class MinStack { private Deque<Integer> stack; private Deque<Integer> minStack; public MinStack() { stack = new LinkedList<>(); minStack = new LinkedList<>(); minStack.push(Integer.MAX_VALUE); } public void push(int val) { stack.push(val); minStack.push(Math.min(val, minStack.peek())); } public void pop() { stack.pop(); minStack.pop(); } public int top() { return stack.peek(); } public int getMin() { return minStack.peek(); } }
public int largestRectangleArea(int[] heights) { int max = 0; for (int i=0; i<heights.length; i++) { int minH = heights[i]; for (int j=i; j<heights.length; j++) { minH = Math.min(heights[j], minH); int area = (j-i+1) * minH; max = Math.max(area, max); } } return max; }
public int largestRectangleArea(int[] heights) { int max = 0; for (int k=0; k<heights.length; k++) { // 找左边界 和右边界 int l = k-1, r = k+1; while (l>=0 && heights[l]>=heights[k]) l--; while (r<=heights.length-1 && heights[r]>=heights[k]) r++; int area = (r-l-1) * heights[k]; max = Math.max(area, max); } return max; }
基于“以当前角标对应的值作为高,再获取到左边界、和右边界,进来计算出面积”
维护一个递增的栈(栈里面存放角标),这样左边界就确定了。
因为是递增,如果进栈元素比栈顶的元素小,那边右边界就也能确定了。
public int largestRectangleArea(int[] heights) { Deque<Integer> deque = new LinkedList<>(); deque.addFirst(-1); int max=0; for (int i=0; i<=heights.length; i++) { if (i==heights.length || (deque.peek()!=-1 && heights[deque.peek()]>heights[i])){ while ((i==heights.length && deque.peek()!=-1) || (deque.peek()!=-1 && heights[deque.peek()]>heights[i])) { int h_i = deque.removeFirst(); while (deque.peek() != -1 && heights[deque.peek()] == heights[h_i]) h_i = deque.removeFirst(); int l_i = deque.peek(); int r_i = i; int area = (r_i - l_i - 1) * heights[h_i]; max = Math.max(area, max); } } deque.addFirst(i); } return max; }
public int largestRectangleArea(int[] heights) { Deque<Integer> deque = new LinkedList<>(); deque.addFirst(-1); int max = 0; for (int i=0; i<heights.length; i++) { while (deque.peek()!=-1 && heights[deque.peek()]>heights[i]) { int area = heights[deque.removeFirst()] * (i-deque.peek()-1); max = Math.max(area, max); } deque.addFirst(i); } while (deque.peek()!=-1) { int area = heights[deque.removeFirst()] * (heights.length - deque.peek()-1); max = Math.max(area, max); } return max; }
public int[] maxSlidingWindow(int[] nums, int k) { int[] res = new int[nums.length-k+1]; Deque<Integer> deque = new LinkedList<>(); for (int i=0; i<nums.length; i++) { while (!deque.isEmpty() && nums[deque.peekLast()]<=nums[i]) { deque.removeLast(); } deque.addLast(i); int j = i-k+1; if (deque.peekFirst()<j) { deque.removeFirst(); } if (j>=0) { res[j] = nums[deque.peekFirst()]; } } return res; }
class MyCircularDeque { private Node first, last; private int N; private int capacity; private class Node{ private int value; private Node next,pre; public Node(int value) { this.value = value; } } public MyCircularDeque(int k) { this.capacity = k; } public boolean insertFront(int value) { if (isFull()) return false; Node node = new Node(value); if (isEmpty()) { first = node; last = node; }else { Node oldFirst = first; first = node; first.next = oldFirst; oldFirst.pre = first; first.pre = last; last.next = first; } N++; return true; } public boolean insertLast(int value) { if (isFull()) return false; Node node = new Node(value); if (isEmpty()) { last = node; first = last; }else { Node oldLast = last; last = node; last.next = first; last.pre = oldLast; first.pre = last; oldLast.next = last; } N++; return true; } public boolean deleteFront() { if (isEmpty()) return false; if (size()==1) { first=null; last =null; }else { Node oldFirst = first; first = oldFirst.next; first.pre = last; last.next = first; } N--; return true; } public boolean deleteLast() { if (isEmpty()) return false; if (size()==1) { first = null; last = null; }else { Node oldLast = last; last = oldLast.pre; last.next = first; first.pre = last; } N--; return true; } public int getFront() { if (isEmpty()) return -1; return first.value; } public int getRear() { if (isEmpty()) return -1; return last.value; } public int size() { return N; } public boolean isEmpty() { return size() == 0; } public boolean isFull() { return size()==capacity; } }
public int trap(int[] height) { if (height==null || height.length<3) return 0; Deque<Integer> deque = new LinkedList<>(); int container = 0; for (int i=0; i<height.length; i++) { while (!deque.isEmpty() && height[i]>height[deque.peek()]) { int lo = deque.removeFirst(); if (deque.isEmpty()) break; int left = deque.peek(); int width = i - left - 1; int high = Math.min(height[i], height[left])-height[lo]; container += width * high; } deque.addFirst(i); } return container; }