题目描述:
给定一个整数序列: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].
上来的想法就是对于其中的每一个元素都向前向后判断一下是否有符合条件的就可以了
//这个代码没有测试过不知道是否正确 下面的一个一定正确
#include<iostream>
#include<vector>
using namespace std;
public:
bool find132pattern(vector<int>& nums) {
int len=nums.size();
if(len<3) return false;
for(int i=1;i<len;i++)//1开始逐渐向后提取每一个判断的元素也就是j
{
//找前面小的
int min=nums[0];
for(int j=0;j<i;i++){
min=min>a[j]?a[j]:min;
}
if(min>nums[i]) break;//如果最小的都比要判断的数大提前进入下一个循环
//找后面比min大的但是比nums[i]小的
for(int j=i+1;i<len;j++){
if(nums[j]>min){
if(nums[i]>nums[j]) return true;
}
}
}
return false;
}
};
对于这种方法我们发现其最坏的时间复杂度为n方 优化一下从前往后不太好想的时候倒着走一走有可能有新发现呢
先上代码 看不明白找个测试用例用笔一步一步执行一下就明白了
bool find132pattern(vector<int> & nums){
if(nums.size()<3) return false;//特殊输入处理
stack<int> max;//从nums数组后往前扫描,这个栈用于存储在某个位置时往后的最大元素,
int len=nums.size();
int cixiao=INT_MIN;//这个变量用来保存次小的元素数值
for(int i=len-1;i>=0;i--){
if(nums[i]<cixiao) return true;//这个时候由于cixiao要比当前的位置大,则可以找到并且cixiao一定出现在nums[i]的后面
while(!max.empty()&& nums[i]>max.top()){
//如果找到了比栈中的还大的元素则将该元素压栈
//这样之前的栈顶元素就是在该状态下的次小元素
//使用cixiao变量保存一下就可以了
cixiao=max.top();
max.pop();
}
max.push(nums[i]);
}
return false;
}
时间复杂度降到n