LeetCode.456 Pattern

题目:

Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list.

Note: n will be less than 15,000.

Example 1:

Input: [1, 2, 3, 4]

Output: False

Explanation: There is no 132 pattern in the sequence.

Example 2:

Input: [3, 1, 4, 2]

Output: True

Explanation: There is a 132 pattern in the sequence: [1, 4, 2].

Example 3:

Input: [-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].
分析(Stack实现):

class Solution {
    class Pair{
        int min,max;
        public Pair(int min,int max){
            this.min=min;
            this.max=max;
        }
    }
    
    public boolean find132pattern(int[] nums) {
       //给定数组,判断其中是否有满足132规则(a subsequence ai, aj, ak such that i < j < k and ai < ak < aj)子序列(满足其中的顺序即可)
        //暴力解法思路:使用堆栈实现,分别从两头开始放入,每次都必须满足大于栈顶。如果栈内元素超过三个,就直接退出(暴力解法:TLM)
        //参考答案:使用一个元素pair对,来存储最大值和最小值,这样只需要满足当前元素在两者之间既返回true
        //注意:如果第二个是最大元素,那么可能会存在无法求解更小的
        
        Stack<Pair> stack=new Stack<Pair>();
        for(int n:nums){
            Pair cur=new Pair(n,n);
            while(!stack.empty()&&cur.max>stack.peek().min){
                cur.min=Math.min(stack.peek().min,cur.min);
                cur.max=Math.max(stack.peek().max,cur.max);
                //出栈
                stack.pop();
            }
            //将更新后的pair放入栈
            stack.push(cur);
            
            //如果当前元素满足两者其中,返回true
            if(stack.peek().min<n&&n<stack.peek().max) return true;
            
        }  
        return false;
    }
}


分析2(参考答案):

class Solution {
    public boolean find132pattern(int[] nums) {
        //给定数组,判断其中是否有满足132规则(a subsequence ai, aj, ak such that i < j < k and ai < ak < aj)子序列(满足其中的顺序即可)
        //暴力解法思路:使用堆栈实现,分别从两头开始放入,每次都必须满足大于栈顶。如果栈内元素超过三个,就直接退出(暴力解法:TLM)
        //使用数组实现
        //注意:如果第二个是最大元素,那么可能会存在无法求解更小的
        
        int min=Integer.MIN_VALUE,top=nums.length;
        for(int i=nums.length-1;i>=0;i--){
            if(nums[i]<min) return true;
            
            while(top<nums.length&&nums[top]<nums[i]){
                //找到中间间隙
                min=nums[top++];
            }
            
            nums[--top]=nums[i];
        }
        return false;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值