leetcode 456: 132模式 (前缀最小值+单调栈)

这篇博客介绍了如何解决LeetCode中的456题,即132模式问题。题意是寻找数组中是否存在一个满足ai < ak < aj的子序列,其中i < j < k。博主提出了解决方案,首先找到数组的前缀最小值,然后通过维护一个单调递减栈来寻找下标最大的中间值。在遍历过程中,如果栈顶元素小于等于前缀最小值,就将其弹出。如果栈顶元素小于当前遍历到的元素,说明找到了132模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解

  • 题意:给定数组a1, a2, …, an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj。 给定数组nums[],判断是否有132模式

  • 题解:此题主要是找到一个下标最大的中间值,下标最小的最小值,和下标中间的最大值。

    • 下标最小的最小值最好找,就是从前往后遍历一遍数组,第j个位置的最小值就是以j为末尾元素的前缀数组的最小值, 因此首先用一个min数组来记录到第j个数字之前出现的最小值
    • 下标最大的中间值则可以通过维护一个单调递减栈来实现。因为要求下标最大,因此我们可以考虑从后往前遍历数组。
      • 每次遍历的时候需要判断栈顶元素是否小于等于前缀最小值(随着下标的减小,前缀最小值可能会增大),如果是,则栈顶将无效,将其pop出来
      • 否则栈顶元素有效,如果此时栈顶元素小于第i个元素,即nums[j] > s.peek()&&s.peek()>min[j],说明已经找到了132模式。
      • 因为栈顶元素是从后往前存储的,对应元素的下标一定不会小于j,此外,前缀最小值是下标i之前的最小值,那么前缀最小值不等于nums[j]的下标也一定是小于j
  • 实现

public boolean find132pattern(int[] nums) {
        boolean flag = false;
        Stack<Integer> s = new Stack<Integer>();
        int n = nums.length;
        if(n < 3) return false; 
        final int N = 15003;
        int []min = new int[N]; 
        min[0] = nums[0];
        for(int i  = 1;i < n;i++)
            min[i] = Math.min(nums[i],min[i-1]);
        
        for(int j = n-1;j >= 0;j--){
            while(!s.empty() && (s.peek() <= min[j])){
                s.pop();
            }
            if(s.empty() || s.peek() >= nums[j]){
                s.push(nums[j]);
            }
            if(s.peek() > min[j] && s.peek() < nums[j]) return true;
        }
        return false;
    }

题目

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值