LeetCode------456. 132 模式
- 问题描述
- 示例
-
-
- [示例 1](#示例 1)
- [示例 2](#示例 2)
- [示例 3](#示例 3)
- 提示
-
- 解决方法
- 代码实现
-
- [暴力算法 O(n^3^)](#暴力算法 O(n3))
- [暴力算法 O(n^2^)](#暴力算法 O(n2))
- 单调栈O(n)
问题描述
给定一个整数数组 nums
,数组中共有 n
个整数。132 模式的子序列由三个整数 nums[i]
、nums[j]
和 nums[k]
组成,并同时满足:
i < j < k
nums[i] < nums[k] < nums[j]
如果 nums
中存在 132 模式的子序列,返回 true
;否则,返回 false
。
示例
示例 1
输入 : nums = [1,2,3,4]
输出 : false
解释: 序列中不存在 132 模式的子序列。
示例 2
输入 : nums = [3,1,4,2]
输出 : true
解释 : 序列中有 1 个 132 模式的子序列:[1, 4, 2]
。
示例 3
输入 : nums = [-1,3,2,0]
输出 : true
解释 : 序列中有 3 个 132 模式的子序列:[-1, 3, 2]
、[-1, 3, 0]
和 [-1, 2, 0]
。
提示
n == nums.length
1 <= n <= 2 * 10^5
-10^9 <= nums[i] <= 10^9
解决方法
这道题有两个方向,一是暴力求解,二是单调栈。
在leetcode上建议使用单调栈,暴力求解有个别用例会过不去。
代码实现
暴力算法 O(n3)
c
//暴力解法O(n^3)
bool find132pattern(int* nums, int numsSize) {
if (numsSize < 3) { //长度小于 3 无法构成
return false;
}
for (int i = 0; i <= numsSize - 3; i++) {
for (int j = i + 1; j <= numsSize - 2; j++) {
for (int k = j + 1; k <= numsSize - 1; k++) {
if (nums[i] < nums[k] && nums[k] < nums[j]) {
return true;
}
}
}
}
return false;
}
暴力算法 O(n2)
c
//暴力优化O(n^2)
bool find132pattern(int* nums, int numsSize) {
if (numsSize < 3) { //长度小于 3 无法构成
return false;
}
for (int j = 1; j < numsSize - 1; j++) {
int min = nums[0];
for (int i = 1; i < j; i++) {
if (nums[i] < min) {
min = nums[i]; //j作为中间下标,找j左边最小,更容易满足条件
}
}
for (int k = j + 1; k < numsSize; k++) {
if (min < nums[k] && nums[k] < nums[j]) {
return true;
}
}
}
return false;
}
单调栈O(n)
c
bool find132pattern(int* nums, int numsSize) {
if (numsSize < 3) {
return false;
}
int max_k = INT_MIN; //存放k的最大值(初始化为最小值)
int* stack = (int*)malloc(numsSize * sizeof(int));
int top = -1; //栈顶下标
for (int i = numsSize; i >= 0; i--) {
if (nums[i] < max_k) {
free(stack);
return true;
}
while (top >= 0 && nums[i] > stack[top]) {
max_k = stack[top--];
}
stack[++top] = nums[i];
}
free(stack);
return false;
}
单调栈可能有点不好理解,下面将给出图例说明。
提示:
-
nums[i] = 1(模式中的"1")
-
max_k = 2(模式中的"2")
-
stack = {4}(模式中的"3")
