【单调栈】LeetCode - 456 . 132模式

456. 132 模式

题目描述

给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。

如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。

进阶:很容易想到时间复杂度为 O(n^2) 的解决方案,你可以设计一个时间复杂度为 O(n logn) 或 O(n) 的解决方案吗?

示例 1:

输入:nums = [1,2,3,4]
输出:false
解释:序列中不存在 132 模式的子序列。
示例 2:

输入:nums = [3,1,4,2]
输出:true
解释:序列中有 1 个 132 模式的子序列: [1, 4, 2] 。
示例 3:

输入:nums = [-1,3,2,0]
输出:true
解释:序列中有 3 个 132 模式的的子序列:[-1, 3, 2]、[-1, 3, 0] 和 [-1, 2, 0] 。

解题思路

所谓「单调栈」就是栈中的元素都是依次递增或者递减的 如 [4, 3, 2, 1]

  • 132模式至少存在三个数字 分别为 min, max, med
  • min, max, med 顺序不可调换
  • 遍历数组找 med 的位置
  • 如果当前遍历大于栈顶元素 则栈的单调性被破坏,清空栈 将当前值压入栈底 将栈底元素作为med
  • 如果 med max 都存在 遍历到 比med小的值 可放入min位置 返回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;

    }

单调栈

 /**
     * 单调栈
     * @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;
    }

猜你喜欢

转载自blog.csdn.net/qq_35655602/article/details/115216365
456