题目链接
思路:单调栈+动态规划
分析:
132 首先13也就是要找到每个数左边是否存在小于等于自己的,这个可以用一个数组dp来记录
dp[0] = nums[0],因为0号元素左边没有元素,然后dp[i] = min(nums[i],dp[i-1]),更新dp
这样也就拿到了每个元素左边包括自己,的最小的元素
此时我们应该有两个数组,nums和dp
然后我们再分析,132,也就是右边出现了一个介于当前元素和当前元素左边最小元素中间的元素,当然,此时可以枚举,但是因为数据量的原因,需要优化,此时可以使用单调栈,栈顶是最小的。
图解举例:
nums={3,5,0,3,4}
首先nums[len-1]入栈
此时栈顶元素大于dp了,并且小于nums了,此时返回true,程序结束。
代码:
class Solution {
public boolean find132pattern(int[] nums) {
int len = nums.length;
if(len<3){
return false;
}
// nums[i] < nums[k] < nums[j]
//nums[i]
int[] dp1 = new int[len];
//初始化dp
dp1[0] = nums[0];
for(int i = 1; i<len;i++){
dp1[i] = Math.min(nums[i],dp1[i-1]);
}
Stack<Integer> stack = new Stack<>();
//入栈
stack.push(nums[len-1]);
//从右往左遍历
for(int i = len-2;i>=0;i--){
//如果栈顶元素小于dp,弹栈
//因为dp越往左边越大,而我们要找的一定是比dp大的元素,所以栈顶如果比dp还小,那肯定不行
while (!stack.isEmpty() && stack.peek() <= dp1[i]){
stack.pop();
}
//如果满足该条件,就是答案,直接返回
if(!stack.isEmpty() && stack.peek() < nums[i]){
return true;
}
//此时满足的条件应该是比dp大,比栈顶小,入栈
stack.push(nums[i]);
}
return false;
}
}
效率优化,模拟栈
代码:
class Solution {
public boolean find132pattern(int[] nums) {
int len = nums.length;
if(len<3){
return false;
}
// nums[i] < nums[k] < nums[j]
//nums[i]
int[] dp1 = new int[len];
dp1[0] = nums[0];
for(int i = 1; i<len;i++){
dp1[i] = Math.min(nums[i],dp1[i-1]);
}
int[] stack1 = new int[len];
int top = -1;
stack1[++top] = nums[len-1];
for(int i = len-2;i>=0;i--){
while (top!=-1 && stack1[top] <= dp1[i]){
top--;
}
if(top!=-1 && stack1[top]<nums[i]){
return true;
}
stack1[++top] = nums[i];
}
return false;
}
}