BM92 最长无重复子数组
知识点哈希双指针数组
描述
给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同。子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
数据范围:,
示例1
输入:
[2,3,4,5]
复制返回值:
4
复制说明:
[2,3,4,5]是最长子数组
示例2
输入:
[2,2,3,4,3]
复制返回值:
3
复制说明:
[2,3,4]是最长子数组
示例3
输入:
[9]
复制返回值:
1
复制
示例4
输入:
[1,2,3,1,2,3,2,2]
复制返回值:
3
复制说明:
最长子数组为[1,2,3]
示例5
输入:
[2,2,3,4,8,99,3]
复制返回值:
5
复制说明:
最长子数组为[2,3,4,8,99]
题解
思路:
- 遍历整个数组,使用一个hash表记录遍历区间中每个数字出现的次数
- 使用双指针left和right记录hash表所代表的区间
- 假设遍历时当前字符为x,先对hash[x]递增
- 如果hash[x] == 2,则表示在arr[left,right)区间中一定存在一个整数的值和arr[right]的值相等,此时最长的长度为len = std::max(len,right-left)
- 如果索引i == arr.size() - 1,那么len = std::max(len,right-left+1)
- 返回len即可
代码如下:
// https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4?tpId=295&tags=&title=&difficulty=0&judgeStatus=0&rp=0&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D295
using namespace std;
int maxLength(vector<int> &arr)
{
std::unordered_map<int, int> m;
int left = 0;
int len = 0;
for (int i = 0; i < arr.size(); ++i)
{
int x = arr[i];
m[x]++;
if (m[x] == 2)// 由于代码逻辑,不会出现m[x] > 2的情况,因为只要出现m[x]=2的情话就会对m[x]递减
{
len = std::max(len, i - left);
while (m[x] > 1)
{
m[arr[left++]]--;// 左边界往右滑动,直到找到第一个值为x的进行递减后跳出循环
}
}
else if (i == arr.size() - 1)
{
len = std::max(len, i - left + 1);
}
}
return len;
}