一、题目描述
在数列 中,如果对于下标 满足 且 ,则称 为一组递增三元组, 为递增三元组的中心。
给定一个数列,请问数列中有多少个元素可能是递增三元组的中心。
输入格式
- 输入的第一行包含一个整数 n。
- 第二行包含 n 个整数 a[1], a[2], …, a[n],相邻的整数间用空格分隔,表示给定的数列。
输出格式
- 输出一行包含一个整数,表示答案。
样例输入
5
1 2 5 3 5
样例输出
2
样例说明
a[2] 和 a[4] 可能是三元组的中心。
评测用例规模与约定
- 对于 50% 的评测用例,2 <= n <= 100,0 <= 数列中的数 <= 1000。
- 对于所有评测用例,2 <= n <= 1000,0 <= 数列中的数 <= 10000。
方法一:暴力
n 最大为 1000,所以 算法运行次数大概为 ,大概 即 10 亿次,肯定超时,所以只能得 的分。
for(int i = 0; i < N-2; i++)
for(int j = i+1; j < N-1; j++)
for(int k = j+1; k < N; k++) {
...
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,
方法二:优化
不必从某两个端点开始枚举。
- 我们可以在区间
[0, p2]
内判断 p2 位置的数是否是该区间[0, p2]
的最大的数。- 如果是,再从
p2
往后继续寻找一个比arr[p2]
要大的数的下标。 - 否则,枚举下一个区间
[0, p2+1]
- 如果是,再从
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
PrintWriter pw = new PrintWriter(System.out, true); //自动刷新
int N = sc.nextInt();
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = sc.nextInt();
}
int count = 0;
for (int i = 1; i < N; i++) {
boolean up = false;
for (int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
up = true;
break;
}
}
if (up == false)
continue;
boolean up2 = false;
for (int k = i + 1; k < N; k++) {
if (arr[k] > arr[i]) {
up2 = true;
break;
}
}
if (up && up2)
count++;
}
System.out.println(count);
}
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,