Google算法题:132模式

来源:互联网 发布:银月网络手游 编辑:程序博客网 时间:2024/06/06 03:27

题目


Given a sequence of n integers a1, a2, ..., an, a 132pattern is a subsequence ai, aj, ak such that i < j < kand 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.

n will be less than 20,000.

样例

Given nums = [1, 2, 3, 4]
return False // There is no 132 pattern in the sequence.

Given nums = [3, 1, 4, 2]
return True // There is a 132 pattern in the sequence: [1, 4, 2].


题目来源:Link

LintCode链接:Link


分析


(1)方法一:利用最小值数组


TC = O(n)+ O(n^2)

SC = O(n)

1)遍历数组,对于 i,找到 0~i 中的小于 nums[i] 的最小值,存在 mins[i] 中,mins[i] 可能等于 nums [i], 这表明其右边没有比他更小的数,不影响后面的判断

2)从右往左遍历数组,维护一个list,里面是按照插入排序排列的,找到小于当前元素的最大值 max,与 min[i] 比较,若 max > mins[i],则找到了一个132


(1)方法二:利用栈


TC = O(n)

SC最坏:O(n)

SC最好:O(1)

1)用 knum 标记 k 代表的值(132模式中的2),Stack 里面存的是遍历到当前位置所有大于 knum的值(相当于132模式中的3),遍历的当前值(相当于132模式中的1),若nums[i] < knum 则表示发现了132

2)遍历过程中,如果当前小于栈顶,则压栈,如果大于栈顶,证明发现了比当前 knum 对应的 “3” 模式更大的数,则 pop 到 nums[i] < stack.peek(),pop的值赋值给knum,就是小于当前 nums[i] 右边的最大值(栈中的元素自顶向下是递减的)

3)有一种可能是 nums[i] 右边小于他的最大值,之前就被弹出,但是不要紧,由于栈里面放的是比当前 knum 大的数,且可定是连续递增的,若遍历中遇到了比栈顶更大的数,更新的 knum可定是比之前的更大,num[i] 都没有机会找自己的 knum,因为既然他的右边小于他的最大值都已经弹出,证明栈里面的都比他大,他只能被放进栈里面。

4)在132模式中,若2模式代表3模式的右边小于3模式的最大,若1模式代表3模式的左边小于3模式的最小,则1模式与2模式之间最大的3模式可定囊括其他3模式,而此方法就是向最大3模式逼近


代码


(1)方法一


public class Solution {    /**     * @param nums a list of n integers     * @return true if there is a 132 pattern or false     */    public boolean find132pattern(int[] nums) {        if(nums==null) return false;        int n = nums.length;        if(n<3) return false;                int[] mins = new int[n];        mins[0] = nums[0];        for(int i=1; i<n; i++){            mins[i] = Math.min(mins[i-1],nums[i]);        }                int max = nums[n-1];        Stack<Integer> s = new Stack<Integer>();        for(int i=n-1; i>-1; i--){            while(!s.isEmpty() && nums[i]<s.peek()){                s.pop();            }            if(s.isEmpty()){                s.add(nums[i]);                continue;            }else{                max = s.peek();                if(max>mins[i])                    return true;                s.add(nums[i]);            }        }        return false;    }}


(2)方法二

public class Solution {    /**     * @param nums a list of n integers     * @return true if there is a 132 pattern or false     */    public boolean find132pattern(int[] nums) {            if(nums == null) return false;        int n = nums.length;        if(n<3) return false;                Stack<Integer> s = new Stack<Integer>();        int knum = Integer.MIN_VALUE;        for(int i=n-1; i>=0; i--){            if(nums[i]<knum) return true;            while(!s.isEmpty() && nums[i]>s.peek()){                knum = s.pop();            }            s.add(nums[i]);        }        return false;    }}




原创粉丝点击