本题可用滑动窗口(双指针)与“上一次出现位置”数组配合来线性解决。
设左右指针分别为 L
、R
,窗口表示当前考虑的子数组区间 [L, R]
,并维护每个数上一次出现的位置 last[x]
。当把 a[R]
纳入窗口时:
a[R]
最近一次出现的位置 last[a[R]]
在当前窗口内(last[a[R]] ≥ L
),说明发生重复,需要把左指针移动到 last[a[R]] + 1
,以保证窗口内元素仍然互不相同;L
。此时所有以 R
结尾且元素互不相同的子数组的起点可以是 L, L+1, …, R
,共有 R - L + 1
个,将其累加到答案中即可。
给定一个长度为 n 的数组 {a1,a2,...,an} 请你计算其中所有子数组中,元素互不相同的子数组个数。
子数组指从原数组中连续选择的一段元素所形成的数组,要求非空。
第一行输入一个整数 n(1≦n≦2x105) 表示数组长度。
第二行输入 n 个整数 a1,a2,...,an(1≦ai≦n),表示数组中的元素。
输出一个整数,表示满足条件的子数组个数。
输入
3
1 2 1
输出
5
说明
所有子数组共 3×4/2=6 个:
[1,1]={1} 合法; [1,2]={1,2} 合法; [1,3]={1,2,1} 存在重复 1,不合法;
[2,2]={2} 合法; [2,3]={2,1} 合法; [3,3]={1} 合法。
合法子数组共有 5 个,故答案为 5 。