lintcode 132 模式
Posted Criya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lintcode 132 模式相关的知识,希望对你有一定的参考价值。
题目要求
给你一个 n 个整数的序列 a1,a2,...,an,一个 132
模式是对于一个子串 ai,aj,ak,满足 i
< j
< k
和 ai
< ak
< aj
。设计一个算法来检查输入的这 n 个整数的序列中是否存在132模式。n
会小于 20,000
。
样例
给你序列 nums = [1,2,3,4]
返回 False
//没有132模式在这个序列中。
给你序列 nums = [3,1,4,2]
返回 True
//存在132模式:[1,4,2]。
分析
这道题刚做的时候没有看清楚题意,结果写成了连续连续三个数的132模式Orz。后来想了挺久没什么思路于是谷歌了一下,搜到了几种做法好好学习了一下。
- 首先我们的目标是,要寻找三个满足某种关系的数是否在一个列表nums[]中出现。很容易想到我们可以用一个三重循环暴力枚举就好了,显然我们是不可能用这种方法的。那有什么方法呢?凭着多年的数学经验,直觉告诉我们,要找三个索引有序的数i, j, k我们应该把目标设为中间那个j。
- 我们可以通过遍历来寻找j,那么找出j后呢?要找最小值的话有个非常好的方法,那就是创建一个数组,数组的值为前“索引”个数的最小值,举个例子
list = [14, 5, 7, 4, 9, 10, 2, 8] minp[0] = 14 //[14]中14最小 minp[1] = 5 //[14, 5]中5最小 minp[2] = 5 minp[3] = 4 minp[5] = 4 . minp[6] = 2 minp[7] = 2 //[14, 5, 7, 4, 9, 10, 2, 8]中2最小
- 在花费O(n)的时间复杂度找出所有位置处的数之前的最小值后,那在我们遍历j时,那么之后只需要把目光集中在判断
nums[j] > nums[k] and minp[j] < nums[k]
那么这个k我们需要怎么找呢?我们可以在这之后用一个二重循环来枚举j,k,但是我们需要更快的方法,我们之所以想用二重循环是因为我们想让j,k的位置同时移动并且记录它们的值,那有没有什么办法可以在一个循环内控制j,k的移动和记录呢?答案是有的,我们可以利用栈,我们利用列表nums和栈Kstack。nums同时负责j,k的移动但只记录j,利用辅助栈Kstack来记录k的值.
- 我们从后往前遍历j,当满足第一个最简单的要求后开始j,k的判断,把不满足条件的j,k中的k压入Kstack,再往前移动,直到满足j值大于k值后再把Kstack中的top值拉出和minp[j]比较即可
1 class Solution: 2 """ 3 @param: nums: a list of n integers 4 @return: true if there is a 132 pattern or false 5 """ 6 7 def find132pattern(self, nums): 8 # write your code here 9 10 Kstack = [] 11 n = len(nums) 12 if n < 3: 13 return False 14 minp = n * [0] 15 minp[0] = nums[0] 16 17 for i in range(1, n): 18 minp[i] = min(minp[i - 1], nums[i]) 19 20 for j in range(n - 1, 0, -1): 21 if nums[j] > minp[j]: 22 max = -sys.maxsize 23 while len(stack) > 0 and nums[j] > Kstack[-1]: 24 max = Kstack.pop() 25 if max > minp[j - 1]: 26 return True 27 Kstack.append(nums[j]) 28 return False
以上是关于lintcode 132 模式的主要内容,如果未能解决你的问题,请参考以下文章