题目描述
解法一:快速排序思想
解题思路
定义两个数组统计第
i
i
i 个位置前的最大值和后的最小值;
遍历数组,当前元素 大于左边元素的最大值 且 小于右边元素的最小值,即为一个 pivot;
参考代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int v[MAXN];
int lmax[MAXN];
int rmin[MAXN];
int ans[MAXN];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &v[i]);
}
lmax[0] = -1;
for (int i = 0; i < n; i++) {
lmax[i + 1] = max(lmax[i], v[i]); //统计最大值
}
rmin[n] = INT_MAX;
for (int i = n - 1; i >= 0; i--) {
rmin[i] = min(rmin[i + 1], v[i]); //统计最小值
}
int cnt = 0;
for (int i = 0; i < n; i++) {
if (lmax[i] < v[i] && v[i] <= rmin[i]) {
ans[cnt++] = v[i];
}
}
printf("%d\n%s", cnt, cnt == 0 ? "\n" : "");
for (int i = 0; i < cnt; i++) {
if (i > 0) printf(" ");
printf("%d", ans[i]);
}
return 0;
}
分析
- 时间复杂度: O ( n ) O(n) O(n);
- 空间复杂度: O ( n ) O(n) O(n);
可以看出,这种方法虽然简单但是时空复杂度都不是最优。
- 左边最大值可以通过不断遍历,维护一个变量即可;
- 右边最小值可使用单调栈维护;
解法二:单调栈
解题思路
根据题意,遍历数组
n
u
m
s
nums
nums,当前元素 大于左边元素的最大值 且 小于右边元素的最小值
M
a
x
(
n
u
m
s
[
0
,
…
,
i
−
1
]
)
<
n
u
m
s
[
i
]
<
M
i
n
(
n
u
m
s
[
i
+
1
,
…
,
n
−
1
]
)
,
i
=
0
,
1
,
…
,
n
−
1
;
Max(nums[0, \dots, i - 1]) < nums[i] < Min(nums[i+1, \dots, n-1]), \ \ \ i = 0, 1, \dots, n-1;
Max(nums[0,…,i−1])<nums[i]<Min(nums[i+1,…,n−1]), i=0,1,…,n−1;即为一个
p
i
v
o
t
pivot
pivot;
倒序遍历数组,维护一个由栈底到栈顶递减的单调栈。
再次正序遍历,当前已遍历元素的最大值为左边元素的最大值,栈顶元素就是右边元素中的最小值。
注: 初始化左边最小值为 -1
参考代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int v[MAXN];
int st[MAXN];
int ans[MAXN];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &v[i]);
}
int top = -1;
for (int i = n - 1; i >= 0; i--) {
if (top == -1 || v[i] < st[top]) st[++top] = v[i]; //栈空或小于栈顶元素入栈
}
int lmax = -1; //初始化左边最大值为 -1
int cnt = 0;
for (int i = 0; i < n; i++) {
if (v[i] > lmax && v[i] <= st[top]) {
ans[cnt++] = v[i];
}
lmax = max(lmax, v[i]); //更新左边最大值
if (v[i] == st[top]) --top; //当前元素为栈顶元素,出栈
}
printf("%d\n%s", cnt, cnt == 0 ? "\n" : "");
for (int i = 0; i < cnt; i++) {
if (i > 0) printf(" ");
printf("%d", ans[i]);
}
return 0;
}
分析
- 时间复杂度: O ( n ) O(n) O(n);
- 空间复杂度: O ( n ) O(n) O(n);