给定一个整数序列: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].
对于左面的数i可以用保存最小值的数组维护,右边的k用单调栈维护,只有小于栈顶才可以入栈,如果大于栈顶,就说明是满足了j<k并且num[j]>num[k],这样右半面的不等式就成立;
然后判断num[k]和num[i]的关系这里k肯定是大于i的,因为minn表示的是当前位置前面的最小值,如果当前的num[k]不满足,退栈,继续判断,直到num[j]<num[k]了,不成立的时候这时候num[j]入栈,继续判断下一个j(要注意的是如果退栈到最后变成了空栈,需要把当前的num[j]入栈,或者刚开始栈顶放入一个巨大巨大的数)
class Solution {
public:
bool find132pattern(vector<int>& nums) {
int minn[15005] = {0};
minn[0] = nums[0];
for(int i = 1;i < nums.size();i++){
minn[i] = min(minn[i-1],nums[i]);
}
stack<int> sta;
for(int j = nums.size() - 1;j >= 0;j--){
if(sta.size() == 0) sta.push(nums[j]);
else{
if(nums[j] <= sta.top()){
sta.push(nums[j]);
}else{
while(sta.size()){
if(sta.top() < nums[j] && sta.top() > minn[j]){
return true;
}
if(sta.top() > nums[j]){
sta.push(nums[j]);
break;
}
sta.pop();
}
if(sta.size() == 0) sta.push(nums[j]);
}
}
}
return false;
}
};