题目:
Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list.
Note: n will be less than 15,000.
Example 1:
Input: [1, 2, 3, 4] Output: False Explanation: There is no 132 pattern in the sequence.
Example 2:
Input: [3, 1, 4, 2] Output: True Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
Example 3:
Input: [-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].分析(Stack实现):
class Solution {
class Pair{
int min,max;
public Pair(int min,int max){
this.min=min;
this.max=max;
}
}
public boolean find132pattern(int[] nums) {
//给定数组,判断其中是否有满足132规则(a subsequence ai, aj, ak such that i < j < k and ai < ak < aj)子序列(满足其中的顺序即可)
//暴力解法思路:使用堆栈实现,分别从两头开始放入,每次都必须满足大于栈顶。如果栈内元素超过三个,就直接退出(暴力解法:TLM)
//参考答案:使用一个元素pair对,来存储最大值和最小值,这样只需要满足当前元素在两者之间既返回true
//注意:如果第二个是最大元素,那么可能会存在无法求解更小的
Stack<Pair> stack=new Stack<Pair>();
for(int n:nums){
Pair cur=new Pair(n,n);
while(!stack.empty()&&cur.max>stack.peek().min){
cur.min=Math.min(stack.peek().min,cur.min);
cur.max=Math.max(stack.peek().max,cur.max);
//出栈
stack.pop();
}
//将更新后的pair放入栈
stack.push(cur);
//如果当前元素满足两者其中,返回true
if(stack.peek().min<n&&n<stack.peek().max) return true;
}
return false;
}
}
分析2(参考答案):
class Solution {
public boolean find132pattern(int[] nums) {
//给定数组,判断其中是否有满足132规则(a subsequence ai, aj, ak such that i < j < k and ai < ak < aj)子序列(满足其中的顺序即可)
//暴力解法思路:使用堆栈实现,分别从两头开始放入,每次都必须满足大于栈顶。如果栈内元素超过三个,就直接退出(暴力解法:TLM)
//使用数组实现
//注意:如果第二个是最大元素,那么可能会存在无法求解更小的
int min=Integer.MIN_VALUE,top=nums.length;
for(int i=nums.length-1;i>=0;i--){
if(nums[i]<min) return true;
while(top<nums.length&&nums[top]<nums[i]){
//找到中间间隙
min=nums[top++];
}
nums[--top]=nums[i];
}
return false;
}
}