【AcWing】【双指针算法】799. 最长连续不重复子序列
·
最长连续不重复子序列
这是一道基于双指针算法的题目,但是想解这道题需要一点额外的思路,第一遍我没想出来,故在此对这道题的思路进行记录。
题目描述与输入输出

思路
这道题目的要求是寻找不包含重复的数的最长子序列,从题目来看可以使用双指针算法来进行求解,使用iii指针向后遍历,使用jjj指针记录合法的区间起点。
问题的难题在于如何对子序列中重复的数进行判断,即判断当前子序列是否满足题目条件。
正确的解决办法是使用另一个数组sss来记录子序列中数字出现的次数,它的角色有点像map,但由于题目描述中提到数字的大小不会大于10510^5105,因此直接使用另一个数组来存储该信息即可。
具体来说,以111作为数组的下标起点,初始化两个指针,使i=1, j=1,在每一次迭代的过程中都使i++,并使得s[a[i]] ++,这里的aaa数组是存储完整序列的数组,s[a[i]] ++的含义是使a[i]这个数在子序列的出现次数加一。
之后使用while循环来对jjj指针进行移动,如果s[a[j]] > 1,则说明a[j]这个数在子序列中出现了超过两次,需要将jjj指针右移,因为包含当前位置的子序列已经不满足“不重复”这条性质,持续地对s[a[j]]进行判断直到满足子序列的条件,停止jjj指针的移动。
此时,使用resresres来对答案进行记录,使得res = max(res, i-j+1)。
最后输出resresres就是最终答案。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn] = {0};
int s[maxn] = {0};
int n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i=1; i<=n; i++) {
cin >> a[i];
}
int res = 0;
for(int i=1, j=1; i<=n; i++) {
s[a[i]] ++;
while(s[a[i]] > 1) {
s[a[j]] --;
j ++;
}
res = max(res, i - j + 1);
}
cout << res;
return 0;
}
更多推荐



所有评论(0)