最长连续不重复子串

简介: 最长连续不重复子串

给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。


输入格式


第一行包含整数 n。


第二行包含 n 个整数(均在 0∼105范围内),表示整数序列。


输出格式


共一行,包含一个整数,表示最长的不包含重复的数的连续区间的长度。


数据范围


1≤n≤105


输入样例:

5
1 2 2 3 5

输出样例:

3


双指针做法通常因为单调性可以把O(n**2)的时间复杂度降为O(n)

双指针一般模板:

1. for (int i = 0,j =0;i<n;i++)
2. while (j<=i&&check(i,j))
3.         j++

对于本题,以J作为左端点,I作为右端点,维护一段合法区间;


I遍历整个数组,不断更新res(答案),求出最优解;


那么该如何求一段合法区间?


给定一个右端点,那么我要尽可能让j靠左,这样才能让长度最大;


假设我们已经有了一段合法区间[j,i],并且有一个记录区间内每个元素出现的次数的数组S。


那么,很显然对于任意X∈[j,i],都有S[X] = 1。


当 i开始后移,就把i对应的值a[i],此时的a[i]对应的S[a[i]]+1;


i每往后移动一步,都要这么做;


若往后移的过程中,新增的元素都不会破坏原区间的合法性,


那么左端点不动,i不断增大,一直更新res;


直到碰到某个下标(不妨设为i+t,t>=1)的时候,使得S[a[i]]>1(=2),破坏了原区间的合法性;


那么此时,在区间[j,i-1]一定有一个下标k使得a[k] = a[i],那么合法区间就是[k+1,i]


那么此时应该更新合法长度 res = max(res,i-(k+1)+1)


那么,由于数组s始终代表对于一对确定的(j,i)区间内的元素的出现的个数,


我们需要将[j,k]的元素都从s剔除,即次数-1,并且令j走到k+1的位置;


那么只需要:

while(a[i]>1) --s[a[j++]]


当且仅当 j = k+1的时候,循环退出,剔除完毕,j走到k+1;


那么此时,我们又得到了以i+t为右端点,k+1为左端点的合法区间,区间恢复合法,res可以更新


很显然对于任意X∈[k+1,i+t],都有S[X] = 1。


本题很巧妙的地方在于,利用数组S,统计元素出现的个数,精妙处 --s[a[j++]]


#include<iostream>
using namespace std;
const int N = 1e5+10;
int a[N],s[N];
int main()
{   
    int n;
    cin >> n;
    int res = 0;
    for(int i = 0,j = 0;i<n;i++)
    {
        cin >> a[i];
        s[a[i]]++;
        while(s[a[i]]>1) --s[a[j++]];
        res = max(res,i-j+1);
    }
    cout<<res;
    return 0;
}

7dd77597c82f49e0976e3451757d8cd7.png

相关文章
|
6月前
|
存储 索引
|
4月前
|
算法 C++
2730. 找到最长的半重复子字符串(c++,滑动窗口)
2730. 找到最长的半重复子字符串(c++,滑动窗口)
|
6月前
|
算法 测试技术 C#
【线段树】2213. 由单个字符重复的最长子字符串
【线段树】2213. 由单个字符重复的最长子字符串
|
6月前
最长连续不重复子序列
最长连续不重复子序列
33 1
|
存储 算法 安全
LeetCode - #3 最长未重复子字符串
我们社区从本期开始会将顾毅(Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。))的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。
剑指offer 49. 最长不含重复字符的子字符串
剑指offer 49. 最长不含重复字符的子字符串
68 0
每日三题-无重复字符的最长子串、最长连续序列、找到字符串中所有字母异位词
每日三题 无重复字符的最长子串 最长连续序列 找到字符串中所有字母异位词
97 1
每日三题-无重复字符的最长子串、最长连续序列、找到字符串中所有字母异位词
|
人工智能 算法 JavaScript
最长连续不重复的序列
最长连续不重复的序列
滑动窗口__最长不含重复字符的子符串_和为S的连续正整数序列(剑指offer)
滑动窗口__最长不含重复字符的子符串_和为S的连续正整数序列(剑指offer)
104 0
滑动窗口__最长不含重复字符的子符串_和为S的连续正整数序列(剑指offer)