|
1 :题目大意 : 输入一个数组 , 求子序列的个数(子序列连续并且不包含重复元素)(题目链接)
Input : 5 1 1 2 1 5
Output : 9
样例解释 :子序列有 (1)(1)(1,2)(2)(2,1)(2,1,5)(1)(1,5)(5)
解题思路1 :
1 :设置一个集合记录不重复元素序列的个数
2 :ans += 集合中的值的大小
3: 用 i 指针来记录答案 ,j 指针始终使集合中不出现重复元素
|
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 99 ;
signed main()
{
int n , a[N] , ans = 0 ;
set<int> s ;
cin >> n ;
for( int i = 1 ; i <= n ; i ++ )
{
cin >> a[i] ;
}
int i = 1 , j = 1 ;
while( i <= n )
{
while( !s.count(a[i]) && i <= n )
{
s.insert(a[i]) ;
ans += s.size( ) ;
i ++ ;
}
while( s.count(a[i]) && j <= n )
{
s.erase(a[j]) ;
j ++ ;
}
}
cout << ans ;
return 0 ;
}
解题思路2 :
1 : 用一个队列记录不重复子序列 , 这个队列就用数组本身
2 : ans += 队列中的个数
3 : 队列始终保持不重复出现元素
|
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 99 ;
int a[N] , n , ans = 0 , fro = 0 ;
map < int ,int > vis ;
signed main()
{
cin >> n ;
for( int i = 1 ; i <= n ; i ++ )
{
cin >> a[i] ;
vis[a[i]] ++ ;
while( vis[a[i]] > 1 )
{
vis[a[++fro]] -- ;
}
ans += i - fro ;
}
cout << ans ;
return 0 ;
}
总结,看似是两种思路 , 实际上它的核心思想: 双指针解法 。
用一个指针记录答案,另外一个指针维护这个没有重复元素的最长子序列。