题目描述
思路解析动画文字版
两件事记牢:窗口内永远无重复;sum 随纳入加、随吐出减,每纳入一个新数就用 sum 刷新 best。下面一步步演给你看。
开始前:窗口是空的,窗口和 sum=0,历史最大 best=0。左右指针都还没出发。
右指针 r 走到下标 0,值是 2。这个值在窗口里没出现过,直接纳入。
把下标 0(值 2)纳入窗口,窗口和增加到 2。用它刷新历史最大,best = 2。
右指针 r 走到下标 1,值是 1。这个值在窗口里没出现过,直接纳入。
把下标 1(值 1)纳入窗口,窗口和增加到 3。用它刷新历史最大,best = 3。
右指针 r 走到下标 2,值是 5。这个值在窗口里没出现过,直接纳入。
把下标 2(值 5)纳入窗口,窗口和增加到 8。用它刷新历史最大,best = 8。
右指针 r 走到下标 3,值是 3。这个值在窗口里没出现过,直接纳入。
把下标 3(值 3)纳入窗口,窗口和增加到 11。用它刷新历史最大,best = 11。
右指针 r 走到下标 4,值是 2。这个值已在当前窗口里,先从左边吐数把它清掉。
从左端吐出下标 0(值 2,标红),窗口和减去它变成 9,左指针右移到 1。重复已清除。
把下标 4(值 2)纳入窗口,窗口和增加到 11。用它刷新历史最大,best = 11。
右指针 r 走到下标 5,值是 6。这个值在窗口里没出现过,直接纳入。
把下标 5(值 6)纳入窗口,窗口和增加到 17。用它刷新历史最大,best = 17。
右指针 r 走到下标 6,值是 1。这个值已在当前窗口里,先从左边吐数把它清掉。
从左端吐出下标 1(值 1,标红),窗口和减去它变成 16,左指针右移到 2。重复已清除。
把下标 6(值 1)纳入窗口,窗口和增加到 17。用它刷新历史最大,best = 17。
右指针 r 走到下标 7,值是 4。这个值在窗口里没出现过,直接纳入。
把下标 7(值 4)纳入窗口,窗口和增加到 21。用它刷新历史最大,best = 21。
右指针 r 走到下标 8,值是 3。这个值已在当前窗口里,先从左边吐数把它清掉。
从左端吐出下标 2(值 5,标红),窗口和减去它变成 16,左指针右移到 3。还有重复,继续吐。
从左端吐出下标 3(值 3,标红),窗口和减去它变成 13,左指针右移到 4。重复已清除。
把下标 8(值 3)纳入窗口,窗口和增加到 16。用它刷新历史最大,best = 21。
扫描结束。所有无重复窗口里,和最大的就是高亮的这一段,best=21 就是最终答案。
三个高频追问:两个变量的含义、为什么不必枚举、以及全相同的边界。
参考代码
def maximumUniqueSubarray(nums): seen = set() # 窗口内已有的数 l = cur = best = 0 # 左指针 / 窗口和 / 答案 for r in range(len(nums)): while nums[r] in seen: # 撞重复 → 从左边吐 seen.remove(nums[l]) cur -= nums[l] l += 1 seen.add(nums[r]) # 纳入新数 cur += nums[r] best = max(best, cur) # 刷新答案 return best复杂度
- 时间:O(n),左右指针各自只从头走到尾一次,每个元素最多被纳入和吐出各一次
- 空间:O(n),用一个集合记录窗口内出现过的数,最坏装下整个数组
易错点
面试追问把动画讲成自己的话
追问sum 和 best 分别代表什么?
追问为什么这题不用先排序或枚举所有子数组?
追问如果数组里全是同一个数,结果是多少?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最高频元素的频数
LeetCode 1838 · 中等 · 沿着 滑动窗口套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题