The stack

A monotonic stack is a stack whose elements must be in ascending or descending order. Stacks in ascending order are called increasing stacks, and stacks in descending order are called decreasing stacks.

Valid string

  1. There are only characters ‘(‘ and ‘)’ in the string. Valid strings require parentheses to pair.

    For example: Input: “()” output: true

    Explanation :(), ()(), (()) are legal. ()()()() is illegal.

    boolean isValid(String s);

   /** * The string contains only characters '(' and ')'. Valid strings require parentheses to pair. For example: Input: "()" Output: true * Explanation: (), ()(), (()) are legal. ()()()() is illegal. * Time complexity O(n) Space complexity O(n) */
    private static boolean isValid(String s) {
        if (null == s || s.length() == 0 || s.length() % 2! =0) {
            return false;
        }

        Stack<Character> stack = new Stack<Character>();
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (stack.isEmpty()) {
                stack.push(chars[i]);
                continue;
            }
            if ('(' == stack.peek() && ') ' == chars[i]) {
                stack.pop();
            } else{ stack.push(chars[i]); }}return stack.isEmpty();
    }
Copy the code

Optimization: the data is pushed (, the elements in the stack are the same, there is no need to use the stack, just the number of elements in the stack.

   /** * Time complexity O(N) Space complexity O(1) */
    private static boolean isValid1(String s) {
        if (null == s || s.length() == 0 || s.length() % 2! =0) {
            return false;
        }

        char[] chars = s.toCharArray();
        int num = 0;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '(') {
                num++;
            } else {
                if (num <= 0) {
                    return false; } num--; }}return num == 0;
    }
Copy the code

Variant: given a include only ‘(‘,’) ‘, ‘{‘,’} ‘, ‘/’, ‘ ‘string, to determine whether a string is effective. A valid string must meet the following requirements:

  • An open parenthesis must be closed with a close parenthesis of the same type
  • The left parentheses must be closed in the correct order
  • Note that an empty string can be considered a valid string
private static boolean isValidC(String s) {
        if (null == s || s.length() == 0 || s.length() % 2! =0) {
            return false;
        }

        Stack<Character> stack = new Stack<Character>();
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (' ' == chars[i]) {
                return false;
            }

            if ('(' == chars[i] || '{' == chars[i] || '[' == chars[i]) {
                stack.push(chars[i]);
                continue;
            }

            if (stack.isEmpty()) {
                return false;
            }

            if (') ' == chars[i]) {
                if ('(' == stack.peek()) {
                    stack.pop();
                } else {
                    return false; }}if ('} ' == chars[i]) {
                if ('{' == stack.peek()) {
                    stack.pop();
                } else {
                    return false; }}if ('] ' == chars[i]) {
                if ('[' == stack.peek()) {
                    stack.pop();
                } else {
                    return false; }}}return stack.isEmpty();
    }
Copy the code
  1. There are a lot of fish in the water, and you can think of them as sitting on the X-axis. Given two arrays Size, Dir, Size[I] denotes the Size of the ith fish, Dir[I] denotes the direction of the fish (0 indicates left, 1 indicates right). The two arrays represent the size and direction of the fish, respectively, and the two arrays are of equal length. The behavior of fish meets the following criteria:

    • All the fish start swimming at the same time, one unit at a time in the direction of the fish.
    • When facing each other, bigger fish eat smaller ones;
    • Fish are all different sizes.

    Enter: Size = [4, 2, 5, 3, 1], Dir = [1, 1, 0, 0, 0]

    Output: 3

    int solution(int[] size, int[] dir)

   /** * Time complexity O(n) Space complexity O(n) */
    private static int solution(int[] size, int[] dir) {

        if (size.length <= 1 || dir.length <= 1|| size.length ! = dir.length) {return size.length;
        }

        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < size.length; i++) {
            boolean hasEat = false;
            while(! stack.isEmpty() && dir[stack.peek()] ==1 && dir[i] == 0) {
                if (size[stack.peek()] > size[i]) {
                    hasEat = false;
                    break;
                }
                stack.pop();
            }

            if (!hasEat) {
                stack.push(i);
            }
        }
        return stack.size();
    }
Copy the code
  1. An array of integers, A, finds each element: the first subscript position on the right that is smaller than me, or -1 if not.

    Input: [5, 2]

    Output: [1, -1]

​ int[] findRightSmall(int[] arr)

    /** * a number always wants to match the number to the left that is larger than it. When a match is made, the smaller number cancels out the larger number. * * Time complexity O(N) space f again O(N) * the position of the first element on the right of the array smaller than me, solved using the increment stack. * * /
    private static int[] findRightSmall(int[] arr) {

        int[] resultArr = new int[arr.length];

        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < arr.length; i++) {
            while(! stack.isEmpty() && arr[stack.peek()] > arr[i]){ resultArr[stack.pop()] = i; } stack.push(i); }while(! stack.isEmpty()){ resultArr[stack.pop()] =-1;
        }
        return resultArr;
    }
Copy the code
  1. Given an array of positive integers and k, it is required to extract k numbers in turn and output a subsequence of the array. The following requirements are met: 1. Length k; 2. Minimum dictionary order.

    Input: nums = [3,5,2,6], k = 2

    Output: [2, 6]

private static int[] findSmallSeq(int[] arr, int k){

        int[] result = new int[k];
        Stack<Integer> stack = new Stack<Integer>();
        for(int i=0; i<arr.length; i++){
            int leftNum = arr.length - i;
            while( !stack.empty() && stack.size()+ leftNum > k && stack.peek()> arr[i]){
                stack.pop();
            }
            stack.push(arr[i]);
        }

        while(stack.size() > k){
            stack.pop();
        }

        for(int i=k-1; i>=0; i--){
            result[i] = stack.peek();
            stack.pop();
        }
        return result;
    }
Copy the code
  1. N non-negative integers are given to represent the heights of the columns in a bar graph. Each column is adjacent to each other and has a width of 1. Find the maximum area of rectangles that can be outlined in the bar chart.

    Input:,1,5,6,2,3 [2]

    Output: 10

   /** * need to find the first number on the left less than A[I], leftPos, also need to find the first number on the right less than A[I]. rightPos */
    private static int largestRectangleArea1(int[] arr){

        int[] leftSmall = findLeftSmall(arr);
        int[] rightSmall = findRightSmall(arr);
        int result =0;

        for (int i = 0; i < arr.length; i++) {
            int leftPos = leftSmall[i];
            int rightPos = rightSmall[i] == -1 ? arr.length: rightSmall[i];

            int width = rightPos - leftPos -1;
            result = Math.max(result, width * arr[i]);
        }
        return result;
    }


    /** * query the left less than */
    private static int[] findLeftSmall(int [] arr){
        int[] resultArr = new int[arr.length];

        Stack<Integer> stack = new Stack<Integer>();
        for (int i = arr.length-1; i > 0; i--) {
            while(! stack.isEmpty() && arr[stack.peek()] > arr[i]){ resultArr[stack.pop()] = i; } stack.push(i); }while(! stack.isEmpty()){ resultArr[stack.pop()] =-1;
        }
        return resultArr;
    }
    /** ** Query the number on the right less than */
    private static int[] findRightSmall(int[] arr) {

        int[] resultArr = new int[arr.length];

        Stack<Integer> stack = new Stack<Integer>();
        for (int i = 0; i < arr.length; i++) {
            while(! stack.isEmpty() && arr[stack.peek()] > arr[i]){ resultArr[stack.pop()] = i; } stack.push(i); }while(! stack.isEmpty()){ resultArr[stack.pop()] =-1;
        }
        return resultArr;
    }
Copy the code
    public int largestRectangleArea(int[] A) {
        final int N = A == null ? 0 : A.length;
        int top = 0;
        int[] s = new int[N];
        int ans = 0;
        for (int i = 0; i <= N; i++) {
            final int x = i == N ? -1 : A[i];
            while (top > 0 && A[s[top - 1]] > x) {
                final int height = A[s[--top]];
                final int rightPos = i;
                final int leftPos = top > 0 ? s[top - 1] : -1;
                final int width = rightPos - leftPos - 1;
                final int area = height * width;
                ans = Math.max(ans, area);
            }
            s[top++] = i;
        }
        return ans;
    }
Copy the code