classSolution: defminSubArrayLen(self, target: int, nums: List[int]) -> int: l = Sum = 0 Len = float("inf") for i inrange(len(nums)): Sum += nums[i] # Sum为当前子数组的和 while Sum >= target: Len = min(Len, i - l + 1) # 有最小 最大要求 就需要进行比较 Sum -= nums[l] # Sum减去当前子数组的起始元素 l += 1 Len = 0if Len == float("inf") else Len # 如果Len没有被赋值,说明没有符合条件的子数组,返回0 return Len
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: intminSubArrayLen(int target, vector<int>& nums){ int l=0, r = 0, sum = 0, len = INT_MAX; for(r=0; r < nums.size(); r++){ //滑动窗口 sum += nums[r]; while(sum >= target){ len = min(len, r-l+1); //记录最小长度 sum -= nums[l++]; //缩小窗口 } } return len == INT_MAX ? 0 : len; } };
3. 变种
☆☆(1)题目:你正在探访一家农场,农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示,其中 fruits[i] 是第 i 棵树上的水果 种类 。你想要尽可能多地收集水果。然而,农场的主人设定了一些严格的规矩,你必须按照要求采摘水果:
classSolution: defminWindow(self, s: str, t: str) -> str: # cnt = Counter(t) # 使用下面的字典方法速度更快 cnt = collections.defaultdict(int) # 使用字典存储 t 中的元素及其个数 for c in t: cnt[c] += 1 cntLen = len(t) left = 0 ans = (0, float('inf')) # for right in range(len(s)): # 使用enum函数直接取元素, 比通过索引查询字符串中的元素要快 # c = s[right] for idx, c inenumerate(s): # 从 s 字符串中取元素 if cnt[c] > 0: cntLen -= 1# 如果当前元素是 t 中元素, 长度 -1 cnt[c] -= 1# 更新字典,字典中对应的 c 元素 -1(如果在t中不存在,值则为-1) if cntLen == 0: # 如果 t 总长度为0, 则说明当前窗口中已经包含了所有的 t 中的元素,准备缩小窗口 whileTrue: if cnt[s[left]] == 0: # 如果当前元素为 t 中的元素,跳出循环(窗口中需要包含 t 中的元素) break cnt[s[left]] += 1# 更新字典,当前元素值 +1 left += 1# 缩小窗口 if idx - left < ans[1] - ans[0]: # 进行比较,更新最小子串 ans = (left, idx) cnt[s[left]] += 1# 下面这三行是因为 s[left] in t,当前窗口的第一个元素当好在 t 中 cntLen += 1# 从上面的 if 中 break 出来了,所以需要对其进行 +1 操作 left += 1# 同时 t 的总长度就也需要对应的 +1,从而使得窗口继续滑动 return''if ans[1] > len(s) else s[ans[0]:ans[1]+1]
根据题目要求,我们需要在字符串 s 寻找字符串 p 的异位词。因为字符串 p 的异位词的长度一定与字符串 p 的长度相同,所以我们可以在字符串 s 中构造一个长度为与字符串 p 的长度相同的滑动窗口,并在滑动中维护窗口中每种字母的数量;当窗口中每种字母的数量与字符串 p 中每种字母的数量相同时,则说明当前窗口为字符串 p 的异位词。
# 使用字典 classSolution: deffindAnagrams(self, s: str, p: str) -> List[int]: len_p = len(p) left, right, ans = 0, len_p, [] cnt_p = collections.defaultdict(int) cnt_s = collections.defaultdict(int) for c in p: # 初始化 p 的字典 cnt_p[c] += 1 for c in s[0:right]: # 初始化 s 的字典,此时只需要和 p 的长度相同 cnt_s[c] += 1 if cnt_p == cnt_s: # 先判断一波是否相等,方便后续窗口移动 ans.append(left) while right < len(s): # 开始移动窗口 一进一出 窗口大小固定 cnt_s[s[right]] += 1 cnt_s[s[left]] -= 1 if cnt_s[s[left]] == 0: # ps: 如果元素为0了,则需要将其删除 del cnt_s[s[left]] left += 1 right += 1 if cnt_p == cnt_s: # 判断是否相等 ans.append(left) return ans