题述
示例
思路
朴素的做法是分别对三个数进行枚举,这样的做法是 O(n^ 3)的,数据范围是 10^4,稳稳超时。
我们可以从 132 的大小特性去分析,如果在确定一个数之后,如何快速找到另外两个数。
-
枚举 i:由于 i 是 132 结构中最小的数,那么相当于我们要从 i 后面,找到一个对数 (j,k),使得 (j,k) 都满足比 i 大,同时 j 和 k 之间存在 j > k 的关系。由于我们的遍历是单向的,因此我们可以将问题转化为找 k,首先 k 需要比i 大,同时在 [i, k] 之间存在比 k 大的数即可
-
枚举 j:由于 j 是 132 结构里最大的数,因此我们需要在 j 的右边中比 j 小的「最大」的数,在 j 的左边找比 j小的「最小」的数。这很容易联想到单调栈,但是朴素的单调栈是帮助我们找到左边或者右边「最近」的数,无法直接满足我们「最大」和「最小」的要求,需要引入额外逻辑。
-
枚举 k:由于 k 是 132 结构中的中间值,这里的分析逻辑和「枚举 i」类似,因为遍历是单向的,我们需要找到 k 左边的 i,同时确保 [i,k] 之间存在比 i 和 k 大的数字。
代码
class Solution {
public:
bool find132pattern(vector<int>& nums) {
stack<int> st;
int n = nums.size(), k = INT_MIN;
for(int i = n - 1; i >= 0; i--){
if(nums[i] < k) return true;
while(!st.empty() and st.top() < nums[i]) {
k = max(k,st.top()); st.pop();
}
st.push(nums[i]);
}
return false;
}
};