def slidingWindow(s: str):
# 用合适的数据结构记录窗口中的数据
window = {}
left = 0
right = 0
while right < len(s):
# come是将移入窗口的字符
come = s[right]
if come not in window:
window[c] = 1
else:
window[c] += 1
# 右指针前移扩大窗口
right += 1
# 更新窗口数据,包括计数器,整体状态变量等
# ...
# 考虑是否移动左指针缩小窗口
while left < right and window needs shrink:
# out 是将移出窗口的字符
out = s[left]
# 缩窗
left += 1
# 更新窗口数据
# ...
总体思路,两个while循环,外面的是右指针,里面的是左指针。先移动右指针,增大窗口,等窗口符合条件,再移动左指针,减小窗口,减小到不符合条件。就进入到外循环右指针,窗口继续扩大到符合条件,等符合条件后,左指针继续右移缩小窗口。如此往复。直到右指针末尾。
这里有几个要解决的问题:
一个是维护符合条件的元素的状态。这里用window这个字典来维护。
第二个是当右指针右移,应该做哪些操作的问题。一般就里改变窗口里对应的键值,比如:如果这个元素符合条件,那些把它对应的值加1,有里还要维护窗口整体的变量。比如窗口里是不是所有键都有值。用一个变量valid来维护,如果都有值,说明窗口符合条件。考虑进入内循环缩小窗口。当我们发现某个字符在 window 的数量满足了 need 的需要,就要更新 valid。不同题目need不同。
第三,左指针右移,应该做哪些操作呢?肯定要判断这个元素去除之后,是不是符合条件的元素,如果是,要做键值的减1操作,还要视情况改变valid,如果valid没有改变,则一直内循环,一直减小窗口,直到不符合条件。
第四,多次外循环,如果得到最小值的问题。这个有多种思路,最好不要增加空间复杂度。
第五,窗口可以用普通字典,但麻烦。最好用collections.defaultdict。它是 Python 中的一个类,是 dict 的子类,提供了一个默认值(default value)的字典结构。默认值指的是当访问一个不存在的键时,defaultdict 会自动创建该键并给定一个默认值,而不会引发 KeyError 异常。
第六,移动 left 收缩窗口时,如果窗口内的字符都是可行解,就进行最小覆盖子串的更新。这样可以从可行解中找到长度最短的最终结果。