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 * 105
-109 <= nums[i] <= 109
题目链接:https://leetcode.com/problems/132-pattern/
题目大意:给一个数组,判断是否存在i < j < k
and nums[i] < nums[k] < nums[j]
题目分析:代码写的比较丑,大致思路是维护从左往右能找到的所有区间(存在包含的区间直接合并掉),然后用类似单调栈的思想只维护栈中的最大最小值即可,有很多显而易见的"剪枝"可以直接看代码
正解:从左往右先预处理一个min数组,min[i]表示从0到i这段的最小值,只要nums[i]!=min[i]就表明存在一组13,然后从右往左维护一个单调栈,只要nums[i]大于栈顶则说明存在32,因为栈内元素下标肯定大于i,再判断是否满足12即可
以下是我的非正解,28ms,时间击败50%
class Solution {
public boolean find132pattern(int[] nums) {
int n = nums.length;
if (n < 3) {
return false;
}
int top = 1, stkmi = nums[0], stkma = nums[0];
int[] mi = new int[n];
int[] ma = new int[n];
int cnt = 0;
for (int i = 1; i < n; i++) {
for (int j = 0; j < cnt; j++) {
if (nums[i] < ma[j] && nums[i] > mi[j]) {
return true;
}
}
if (nums[i] > stkma) {
stkma = nums[i];
top++;
} else {
if (nums[i] == stkma) {
continue;
}
if (top == 1) {
stkma = nums[i];
stkmi = nums[i];
continue;
}
if (nums[i] > stkmi) {
return true;
}
if (stkmi + 1 < stkma) {
boolean combined = false;
for (int k = 0; k < cnt; k++) {
if (mi[k] < stkmi && ma[k] > stkma) {
combined = true;
break;
}
if (mi[k] > stkmi && ma[k] < stkma) {
mi[k] = stkmi;
ma[k] = stkma;
combined = true;
break;
}
}
if (!combined) {
mi[cnt] = stkmi;
ma[cnt++] = stkma;
}
}
top = 1;
stkma = nums[i];
stkmi = nums[i];
}
}
return false;
}
}