1. 描述
给定一个长度为n的数组,数组中的每个元素满足:1 <= a <= n;
求这个数组有多少个子区间,使得在这个子区间存在数字v,使得v在这个子区间出现的次数 >= m;
示例
输入
5 2
1 2 1 4 2输出
4
解释:[1, 3], [1, 4], [1, 5], [2, 5]都存在一个数字使得这个数字出现次数 >= 2
示例2
输入
7 3
1 2 1 1 2 4 2
输出
5
解释:[1, 4], [1, 5], [1, 6], [1, 7], [2, 7]
2. 思路与代码
解题思路:
- 用map来保存同一个数字出现的位置;
- 当把当前数字num加入map中的对应位置后,如果当前数字在这之前出现超过了m次,则从当前开始向前数m个当前数字num,得到这倒数第m个出现的当前数字num的位置index;
- 那么区间[1, i], [2, i], …, [index, i]都是满足条件的区间,因为都至少有一个数字出现次数 >= m; 且后面随着
i
的递增区间的右边也也可以随着扩展,因为都满足至少有一个数字出现次数 >= m ; - 在遍历的过程中,在当前数字之前可能已经有数字能满足条件了,因此要使用一个变量来存储当前数字之前出现超过m次的位置;
代码
Java
import java.util.*;
public class Main{
private static List<List<Integer>> all = new ArrayList<>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
Map<Integer, List<Integer>> map = new HashMap<>();
int res = 0;
int pre = 0; // pre记录当前数字之前出现了m次的数字的第一次出现的位置