给定一个整数序列:a1, a2, …, an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj。设计一个算法,当给定有 n 个数字的序列时,验证这个序列中是否含有132模式的子序列。
注意:n 的值小于15000。
示例1:
输入: [1, 2, 3, 4]
输出: False
解释: 序列中不存在132模式的子序列。
示例 2:
输入: [3, 1, 4, 2]
输出: True
解释: 序列中有 1 个132模式的子序列: [1, 4, 2].
示例 3:
输入: [-1, 3, 2, 0]
输出: True
解释: 序列中有 3 个132模式的的子序列: [-1, 3, 2], [-1, 3, 0] 和 [-1, 2, 0].
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/132-pattern
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:从左到右遍历3(最大),遍历的同时维护左边的min,找右边是否有大于min小于3的值。
//这是copyleetcode题解的
class Solution {
public boolean find132pattern(int[] nums) {
int n = nums.length;
if (n < 3) {
return false;
}
// 左侧最小值
int leftMin = nums[0];
// 右侧所有元素
TreeMap<Integer, Integer> rightAll = new TreeMap<Integer, Integer>();
for (int k = 2; k < n; ++k) {
rightAll.put(nums[k], rightAll.getOrDefault(nums[k], 0) + 1);
}
for (int j = 1; j < n - 1; ++j) {
if (leftMin < nums[j]) {
Integer next = rightAll.ceilingKey(leftMin + 1);
if (next != null && next < nums[j]) {
return true;
}
}
leftMin = Math.min(leftMin, nums[j]);
rightAll.put(nums[j + 1], rightAll.get(nums[j + 1]) - 1);
if (rightAll.get(nums[j + 1]) == 0) {
rightAll.remove(nums[j + 1]);
}
}
return false;
}
}