原题链接:
题解:
本题如果采用暴力求解会T,因此最好采用双指针算法在O(n)内求解。
思路:首先定义一个指针i,然后定义一个指针j,以i为区间的右端点,来寻求以j为区间左端点的最大不重复子区间。用数组S记录元素的个数来判断有无重复,当无重复时,j不动,i一直向右;当有重复时,i不动,j向右直到区间内无重复元素为止。
双指针参考模板:
双指针算法的精髓在于通过使用两个指针来协同工作,从而在一次遍历中解决问题。这种技术通常用于数组或链表等数据结构,具体的应用有多种形式。
以下是一些双指针算法的常见应用:
快慢指针: 通过设置两个指针,一个移动速度较快,另一个移动速度较慢,可以解决环的检测、链表中点的查找等问题。
左右指针: 在数组中,设置两个指针分别指向数组的两端,根据问题的特性,通过移动指针来解决问题,比如两数之和、三数之和等。
滑动窗口: 通过维护一个窗口,通常是一个区间或子数组,通过两个指针移动来调整窗口,解决一些子数组或子字符串的最优问题。
对撞指针: 在有序数组中,通过设置两个指针从数组两端开始,根据问题的性质,移动指针来寻找目标。
这些技术的共同点在于通过设置两个指针,根据问题的特性,通过协同工作的方式达到解决问题的目的。这种方法通常可以在 O(n) 的时间复杂度内解决问题,而不需要嵌套遍历。在实际应用中,双指针算法可以提高代码的效率和简洁性。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], s[N];
int n;
int main() {
cin >> n;
for (int i = 0;i < n;i++) cin >> a[i];
int res = 0;
for (int i = 0, j = 0;i < n;i++) {
s[a[i]]++;
while (s[a[i]] > 1) {
s[a[j]]--;
j++;
}
res = max(res, i - j + 1);
}
cout << res;
}