这类题目往往涉及到最长子串或者最小覆盖子串,如力扣第3题无重复字符的最长子串以及第76题最小覆盖子串。
3.无重复字符的最长子串
class Solution: def lengthOfLongestSubstring(self, s: str) -> int: #动态滑动窗口 cnt = Counter() ans = 0 left = 0 for right, c in enumerate(s): cnt[c] += 1 #缩小当前窗口 因为已经出现重复了 while cnt[c] > 1: cnt[s[left]] -= 1 #开始缩小窗口 看看到底哪里重复 直到left移动到重复值的地方 left += 1 #未出现重复 计算最长的地方 ans = max(ans, right-left +1) return ans
难点1:如何去保证无重复的子串,这里涉及到了字典,如果字典中某一个字符C大于1 说明已经重复;
难点2.如何查找重复的地方,保证窗口内是不重复的,这时候就需要缩小窗口
76.最小覆盖子串
class Solution: def minWindow(self, s: str, t: str) -> str: if not s or not t or len(s) < len(t): return '' #涵盖 看可以用dict来记录 ans_left, ans_right = -1, len(s) cnt_s = Counter() cnt_t = Counter(t) #这个来统计t中的字符数量 用于后续覆盖贩毒案 left = 0 for right, c in enumerate(s): cnt_s[c] += 1 while cnt_s >= cnt_t: #覆盖 条件 if right - left < ans_right - ans_left: #说明找到了一个更短子串 ans_right, ans_left = right, left #在这个窗口进行一个缩小 cnt_s[s[left]] -= 1 #窗口缩小 直接在cnt_s里面减掉就可以 left += 1 #移动左指针 return '' if ans_left < 0 else s[ans_left:ans_right + 1]
难点1:覆盖如何判断?使用两个哈希表去统计每一个字符出现的个数,然后比较大小(这个使用方法可以记住)
难点2:跟上面3题一样,动态缩小窗口