LeetCode 456 132 Pattern (单调栈 推荐)

Given an array of n integers nums, a 132 pattern is a subsequence of three integers nums[i]nums[j] and nums[k] such that i < j < k and nums[i] < nums[k] < nums[j].

Return true if there is a 132 pattern in nums, otherwise, return false.

Example 1:

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

Example 2:

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

Example 3:

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

Constraints:

  • n == nums.length
  • 1 <= n <= 2 * 105
  • -109 <= nums[i] <= 109

题目链接:https://leetcode.com/problems/132-pattern/

题目大意:给一个数组,判断是否存在i < j < k and nums[i] < nums[k] < nums[j]

题目分析:代码写的比较丑,大致思路是维护从左往右能找到的所有区间(存在包含的区间直接合并掉),然后用类似单调栈的思想只维护栈中的最大最小值即可,有很多显而易见的"剪枝"可以直接看代码

正解:从左往右先预处理一个min数组,min[i]表示从0到i这段的最小值,只要nums[i]!=min[i]就表明存在一组13,然后从右往左维护一个单调栈,只要nums[i]大于栈顶则说明存在32,因为栈内元素下标肯定大于i,再判断是否满足12即可

以下是我的非正解,28ms,时间击败50%

class Solution {
    public boolean find132pattern(int[] nums) {
        int n = nums.length;
        if (n < 3) {
            return false;
        }
        int top = 1, stkmi = nums[0], stkma = nums[0];
        int[] mi = new int[n];
        int[] ma = new int[n];
        int cnt = 0;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < cnt; j++) {
                if (nums[i] < ma[j] && nums[i] > mi[j]) {
                    return true;
                }
            }
            if (nums[i] > stkma) {
                stkma = nums[i];
                top++;
            } else {
                if (nums[i] == stkma) {
                    continue;
                }
                if (top == 1) {
                    stkma = nums[i];
                    stkmi = nums[i];
                    continue;
                }
                if (nums[i] > stkmi) {
                    return true;
                }
                if (stkmi + 1 < stkma) {
                    boolean combined = false;
                    for (int k = 0; k < cnt; k++) {
                        if (mi[k] < stkmi && ma[k] > stkma) {
                            combined = true;
                            break;
                        }
                        if (mi[k] > stkmi && ma[k] < stkma) {
                            mi[k] = stkmi;
                            ma[k] = stkma;
                            combined = true;
                            break;
                        }
                    }
                    if (!combined) {
                        mi[cnt] = stkmi;
                        ma[cnt++] = stkma;
                    }
                }
                top = 1;
                stkma = nums[i];
                stkmi = nums[i];
            }
        }
        return false;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值