Tuesday, September 19, 2017

[LeetCode]132 Pattern


假设我们从左向右遍历,每找到一个符合条件的pair(a, b),a < b,之后我们如果碰到在(a, b)范围内的数就说明我们找到了符合条件的pattern。但问题是我们可能有多个这样的pair,这样符合要求的区间也可能有多个,这样让我们并不好判断当前数是否符合条件。如果换一种思维,从右向左依次遍历的话,我们可以发现可以简单很多,对于处在i位置的数nums[i],如果存在j > i的数满足nums[i] > nums[j],我们只需要判断在[i + 1, len - 1]区间里,小于nums[i]的最大数c是什么即可,以后如果我们遇到小于c的数就说明我们找到了这样一个pattern。那么我们将这道题转化为对于nums[i]我们如何求出[i + 1, len - 1]小于nums[i]的最大数c。很显然,如果用我们熟知的数据结构,BST可以帮我们做到这一点,时间复杂度为O(n * log n)。但是这里还是依然有重复的计算,假设我们在遍历到b的时候找到了c,我们遇到了一个比b更大的数x,那么我们需要去更新c,因为x的存在可能可以让c变得更大,这样我们找132pattern的第一个数的限制条件会更宽松。那么这一次更新的过程,我们完全就不需要考虑之前在b已经排除的数字了。如果我们用stack维护一个从右向左的递减序列,每当我们碰到了比栈顶更大的数curr,我们pop直到我们得到比curr小的最大值,那么我们就得到了c,同时排除了所有我们之后不需要考虑的数,我们继续插入curr继续之前的步骤,直到我们找到pattern或者发现不存在pattern。这样的话,每个数最多只会在栈上进出一次,时间复杂度O(n),空间复杂度O(n),代码如下:


值得一提的是,维护单调序列来避免重复计算的思路在很多题当中都有出现。比如: Largest Rectangle in Histogram,  Sliding Window Maximum

No comments:

Post a Comment