456. 132 模式
456. 132 模式
🟠 🔖 栈 数组 二分查找 有序集合 单调栈 🔗 力扣 LeetCode
题目
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 a132 pattern in nums , otherwise, returnfalse .
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.length1 <= n <= 2 * 10^5-10^9 <= nums[i] <= 10^9
题目大意
给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。
如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。
示例 1:
输入: nums = [1,2,3,4]
输出: false
解释: 序列中不存在 132 模式的子序列。
示例 2:
输入: nums = [3,1,4,2]
输出: true
解释: 序列中有 1 个 132 模式的子序列: [1, 4, 2] 。
示例 3:
输入: nums = [-1,3,2,0]
输出: true
解释: 序列中有 3 个 132 模式的的子序列:[-1, 3, 2]、[-1, 3, 0] 和 [-1, 2, 0] 。
提示:
n == nums.length1 <= n <= 2 * 10^5-10^9 <= nums[i] <= 10^9
解题思路
目标:找到一个满足 nums[i] < nums[k] < nums[j] (i < j < k) 的 132 模式。
我们可以利用 单调栈 来高效地维护 nums[j](132 模式中的第二个元素),从而在 O(n) 时间复杂度内解决问题。
倒序遍历
numsnums[k]必须出现在nums[j]之后,因此倒序遍历nums,先找到nums[j],从而确保nums[i] < nums[k] < nums[j]。
使用单调递减栈维护
nums[j]stack存储可能的nums[j],并保持单调递减(栈顶元素最大)。
使用
third存储可能的nums[k]- 当
stack不为空,且stack栈顶元素小于当前nums[i],说明stack.pop()是一个合适的nums[k],将third = stack.pop()进行更新。 - 然后将当前
nums[i]放入栈顶,这样就确保了nums[k] < nums[j]。
- 当
判断
nums[i]是否满足nums[i] < third- 如果
nums[i] < third,说明找到了132模式,直接返回true。
- 如果
复杂度分析
- 时间复杂度:
O(n),每个元素最多入栈、出栈一次,总共O(n)。 - 空间复杂度:
O(n),最坏情况下栈存储n个元素。
代码
/**
* @param {number[]} nums
* @return {boolean}
*/
var find132pattern = function (nums) {
let stack = [];
let third = -Infinity;
for (let i = nums.length - 1; i >= 0; i--) {
if (nums[i] < third) return true;
while (stack.length && stack[stack.length - 1] < nums[i]) {
third = stack.pop();
}
stack.push(nums[i]);
}
return false;
};
