题解 | #最长无重复子数组#
最长无重复子数组
https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4
2022.0822算法第40题最长无重复子数组
这题和leetcode第三题无重复字符的最长子串是一样的
可以使用滑动窗口进行求解。
第二次了这个也没写对,很离谱,删除元素时没搞懂怎么删除。
首先,定义start指针,和最大长度初始值,
要明确循环的变量表示的是窗口结束的指针,
主要思想为:将start指针指向0,先对结束指针进行遍历,
直到找到又重复数字存在,此时需要对start指针进行移动,这部分是最难的。
需要将start指针移动到重复数字的下一位
例如{1,2,3,4,2,5,6}
当i=4时,出现重复元素2,需要将start指针指向第一个2的后面一个元素3,也就是start=2;
同时还需要进行其他操作,例如将set更新去除重复数字之前的数,
还是上面的例子,当i=4时,start更新的同时,需要将1和2这两个元素从set中去除,以免影响后面的查找判断。
我就是这点出问题了,我只想着把重复的数字删除,没顾及重复数字之前的数字,必须连续
(这点考虑出错,是因为子串,要求是连续的,如果是子序列,可能就能得到正确的结果)
int maxLength(vector<int>& arr) { //定义开始指针和最大长度初始化 int start=0,max_l=0; //定义set,用于查找重复元素 unordered_set<int> nums; //对结束指针进行遍历 for(int i=0;i<arr.size();i++){ //当结束指针遍历到,出现重复数字的时候 while(nums.find(arr[i])!=nums.end()){ //将重复数字之前的数值全部清除,要求子串是连续的,这点要注意 nums.erase(arr[start]); //同时向前移动start指针,最终指向重复元素的下一位 start++; } //当没有重复元素出现时,将当前元素加入set nums.insert(arr[i]); //nums.insert(arr[i],i); //并更新当前的最大子串长度 max_l=max(max_l,i-start+1); } return max_l; }代码是看明白了,感觉滑动窗口还是挺难想的,两个指针进行移动,主要是start指针进行移动,这点不好想。
还需要注意其他的变量,leetcode209大于target的长度最小的子数组也是采用滑动窗口的思想
209这道题目还简单一点,并没有多余的变量需要处理。
需要维护的变量为sum,在end指针右移的时候sum加上当前值
start指针前移的时候sum减去start指向的值。
这里面的sum和上面的nums变量是一样的作用。
sum和nums存储的都是两个指针区间内的值,当两个指针进行移动的时候,
sum和nums的值就需要更新。