Given an array of n integers nums, a 132 pattern is a subsequence of three integers nums[i], nums[j] and nums[k] such that i < j < k and nums[i] < nums[k] < nums[j].
Return true if there is a 132 pattern in nums, otherwise, return false.
Example 1:
Input: nums = [1,2,3,4]
Output: false
Explanation: There is no 132 pattern in the sequence.
Example 2:
Input: nums = [3,1,4,2]
Output: true
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
Example 3:
Input: nums = [-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].
Constraints:
n == nums.length
1 <= n <= 2 * 10^5
-10^9 <= nums[i] <= 10^9
Didn’t even come up with n 2 n^2 n2 solution, I feel so bad.
Scan from left to right, keep track of the minimum value, and at each point scan the right of the list, to find the middle element.
Time complexity:
o
(
n
2
)
o(n^2)
o(n2)
Space complexity:
o
(
1
)
o(1)
o(1)
Solved after help.
We are going to search for a subsequence s1, s2, s3, that s1 < s3 < s2. s3 should be as large as possible if we could find a s2 that satisfies s2 > s3. So we could use a decreasing stack to store all the elements from right to left, if the current number is larger than the top element, then the element we pop from the stack is a candidate for s3.
Time complexity:
o
(
n
)
o(n)
o(n)
Space complexity:
o
(
n
)
o(n)
o(n)
class Solution:
def find132pattern(self, nums: List[int]) -> bool:
min_val = nums[0]
for j in range(1, len(nums)):
if nums[j] <= min_val:
min_val = nums[j]
continue
else:
for k in range(j + 1, len(nums)):
if min_val < nums[k] < nums[j]:
return True
return False
class Solution:
def find132pattern(self, nums: List[int]) -> bool:
stack = []
s3 = None
for each_num in nums[::-1]:
while stack and stack[-1] < each_num:
if s3:
s3 = max(s3, stack.pop())
else:
s3 = stack.pop()
stack.append(each_num)
if s3 and each_num < s3:
return True
return False