相信大家都是看完y总的课来看博客解惑的我会在这里分享一些我理解的细节
回顾一下题目
直接上代码
#include<iostream> using namespace std; const int N = 1e5+10; int n; //s[N]来存贮从j 到 i的这个区间内的数字出现的次数(这里的j到i是没有重复数字的区间) //j是一直往右走的那么它之前经过的数字也就没用了,s[]数组中也就没必要存储他们的出现次数了 //如果还存着他们的次数的话还可能影响下面操作的进行 //这也是为什么要s[a[j]]--的具体原因 int a[N],s[N]; int main(){ cin>>n; int res = 0; for (int i = 0;i < n;i++) scanf("%d",&a[i]); for (int i = 0,j = 0;i < n;i++){ //s[a[i]]这样存储可以存下来相同数字的数量 因为数字相同的时候s[]数组的下标相同 //所以当a[]数组中的出现相同的数字的时候在s[]中都是同一个位置 s[a[i]]++; while(j <= i && s[a[i]] > 1){ //其中j<=i可有可无 s[a[j]]--; j++; } res = max(res,i - j + 1); } cout<<res; return 0; }
1.
先看看 为什么 j 是单调的(只能往右走)
因为j和i这个区间内一定是最长的不重复区间所以j只要往左移动就会矛盾导致重复(不懂来看一个例子)
123445678
不难看出当 i 指向第二个4的时候(及重复的时候) j 就会移动当移动到和 无重复 数字的时候停止
所以j的位置前一个位一定会在j - i这个范围内有一个数字重复
2.
为什么j <= i可有可无,因为只有在区间内出现重复元素的时候j才会移动当j = i 的时候只有一个数组,绝对无重复,所以在j = i的时候一定会停止,最多达到j = i
3.
这两个步骤怎么理解 s[a[j]]-- ; j++;
为什么要 s[a[j]]--
看这样一个例子
如果各位还有更好的理解思路和我的思路有问题都可以告诉我更正