[Monotone stack] LeetCode-456. 132 mode

456. 132 Mode

Title description

Give you an integer array nums, there are a total of n integers in the array. The subsequence of the 132 pattern consists of three integers nums[i], nums[j] and nums[k], and satisfies at the same time: i <j <k and nums[i] <nums[k] <nums[j].

If there is a subsequence of pattern 132 in nums, return true; otherwise, return false.

Advanced: It is easy to think of a solution with a time complexity of O(n^2). Can you design a solution with a time complexity of O(n logn) or O(n)?

Example 1:

Input: nums = [1,2,3,4]
Output: false
Explanation: There is no subsequence of 132 pattern in the sequence.
Example 2:

Input: nums = [3,1,4,2]
Output: true
Explanation: There is a subsequence of 132 pattern in the sequence: [1, 4, 2].
Example 3:

Input: nums = [-1,3,2,0]
Output: true
Explanation: There are 3 subsequences of 132 pattern in the sequence: [-1, 3, 2], [-1, 3, 0] and [ -1, 2, 0].

Problem-solving ideas

The so-called "monotonic stack" means that the elements in the stack are sequentially increasing or decreasing, such as [4, 3, 2, 1]

  • There are at least three numbers in 132 mode: min, max, med
  • The order of min, max, med cannot be changed
  • Traverse the array to find the position of med
  • If the current traversal is greater than the top element of the stack, the monotonicity of the stack is destroyed, clear the stack, push the current value to the bottom of the stack, and use the bottom element of the stack as med
  • If med max exists and traverse to a value smaller than med, it can be placed in the min position and return true

    /**
     * 暴力求解 时间复杂度 o(n^3)
     * @param nums
     * @return
     */
    public static boolean find132pattern_1(int[] nums) {
    
    
        if (nums.length < 3){
    
    
            return false;
        }
        for (int i = 0; i < nums.length; i++) {
    
    
            for (int j = i + 1; j < nums.length; j++) {
    
    
                for (int k = j + 1; k < nums.length; k++) {
    
    
                    if (nums[k] > nums[i] && nums[k] < nums[j]){
    
    
                        return true;
                    }
                }
            }
        }
        return false;

    }

Monotonic stack

 /**
     * 单调栈
     * @param nums
     * @return
     */
    public static boolean find132pattern(int[] nums){
    
    
        int len = nums.length;
        if (len < 3){
    
    
            return false;
        }
        Stack<Integer> st = new Stack<>();
        int k = -1;
        for (int i = len - 1;i >= 0 ;i--){
    
    
            if (k > - 1 && nums[k] > nums[i])  //找到num[i]
                return true;
            while (!st.isEmpty() && nums[st.peek()] < nums[i])
                k = st.pop(); //pop() 出去的最后一个元素就是 比 num[i] 小的所有元素中的最大元素 nums[k] 。
            st.push(i);
        }
        return false;
    }

Guess you like

Origin blog.csdn.net/qq_35655602/article/details/115216365