Description
给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。 子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组(是子序列)。
输入格式
第一行一个整数n表示数组的长度,n<=100000。 第二行n个整数,int范围。
输出格式
输出最长无重复元素子数组长度。
输入样例
7 2 2 3 4 89 9 3
输出样例
5
滑动窗口类型的题目,其实就是去找到解的左右端点,在这里我们先遍历右端点,然后去找有没有已经遍历过的在左端点右边的数与右端点所指向的数相同,如果相同,那么我们就更新左端点(其实就是左端点向右端点靠近)
#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<queue>
#include<list>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
#include<iomanip>
using namespace std;
map<int, int>m;
int main()
{
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(0);
vector<int>a, v;
int n;
cin >> n;
int ans = 0;
for (int i = 1; i < n; i++)
{
int num;
cin >> num;
a.push_back(num);
}
int r = -1;
int i;
for (i = 0; i < a.size(); i++)
{
if (m.count(a[i])&&m[a[i]] > r)
{
r = m[a[i]];
m[a[i]] = i;
}
else
{
m[a[i]] = i;
}
ans = max(ans, i - r);
}
cout << ans;
}
优化:
在这里我们可以用一下unordered_set,这个数据结构的查找和插入所需要的时间复杂度几乎为常数阶
#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<queue>
#include<list>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
#include<unordered_set>
using namespace std;
int lengthOfLongestSubstring(vector<int>s) {
if (s.size() == 0) return 0;
unordered_set<int> lookup;
int maxStr = 0;
int left = 0;
for (int i = 0; i < s.size(); i++) {
while (lookup.find(s[i]) != lookup.end()) {
lookup.erase(s[left]);
left++;
}
maxStr = max(maxStr, i - left + 1);
lookup.insert(s[i]);
}
return maxStr;
}
int main()
{
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(0);
vector<int>v;
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int num;
cin >> num;
v.push_back(num);
}
cout << lengthOfLongestSubstring(v);
}