Leetcode 456: 132 Pattern
分类:Stack
难度:M
描述:给了一个列表,问列表中存不存在满足“132”型的元素。所谓“132”型,即当i<j<k
时,数组元素ai<ak<aj
.
Input: [1, 2, 3, 4]
Output: False
Explanation: There is no 132 pattern in the sequence.
Input: [3, 1, 4, 2]
Output: True
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
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].
链接: 132 Pattern.
思路:
132类型其实很好理解,此题的解法也不难。
我们从后往前遍历,假设我们遍历到位置i的nums[i]是我们想要的“3”,那么去哪里找“2”呢?这时我们需要一个栈,把之前遍历到的元素(即i之后位置的元素)放入栈中。如果栈顶元素“2”符合,那么已经找到了一个潜在的“132”。
至于“132”中的“1”,我们要保证他是“132”元素而不是“232”甚至“432”,这时需要一个新的list。list里头存的是nums[i]元素的左边中最小的元素,即leftmin。此时我们只要在保证leftmin[i] < stack.pop()即可。因为leftmin[i]是一定小于nums[i]的。
代码如下:
class Solution:
def find132pattern(self, nums: List[int]) -> bool:
if not nums or len(nums)<3:
return False
leftmin = [0 for _ in range(len(nums))]
leftmin[0] = nums[0] 第一个元素左边比他还小的元素是不存在的,所以这个位置直接用nums[0]补上
for i in range(1, len(nums)):
leftmin[i] = min(leftmin[i-1], nums[i-1])
stack = []
for i in range(len(nums)-1, -1, -1):
second = -2**31
while stack and stack[-1]<nums[i]: 找到元素“2”
second = stack.pop()
if second > leftmin[i]:
return True
stack.append(nums[i]) 入栈
return False
个人总结:
1)首先是leftmin的设计。这个list首元素就是它自己。同时,在python中不可以用 leftmin = []来声明此处需要的list。
2)此题的tricky之处即在使用一个stack来存储我们的“2”元素,然后从后往前遍历找到“3”元素。