今天是同向双指针的例题:滑动窗口的题目
1.209 2.3 3.713 4.3090 5.2958 6.2730 7.1004 8.2962 9.2302 10.1658 11.3795 12.76
题目有点多,家人们我可以做到吗?

第一题:突然发现for while这种嵌套就符合:一个等你另一个追的那这种感觉的模型。
python
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left = 0
ans = len(nums)+1
cacu = 0
for right, x in enumerate(nums):
cacu += x
while cacu >= target:
ans = min(ans,right-left+1)
cacu -= nums[left]
left += 1
return ans if ans != len(nums)+1 else 0
第二题:挺简单的,就是要知道有一个工具Counter()。这个字典的key是字母或者一些标识,key是一个数字,可以统计的数字。

python
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
cnt = Counter()
left = 0
ans = 0
for right, x in enumerate(s):
cnt[x] +=1
while cnt[x] >1:
cnt[s[left]] -=1
left +=1
ans = max(ans, right-left+1)
return ans
第三题:

这题也是用滑动指针,不过有一些条件不一样了,还有就是内部的循环条件其实是这些题的变数,外层就是一个一直往右的指针。
python
class Solution:
def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
ans = 0
cacu = 1
if k == 0:
return ans
left = 0
for right, x in enumerate(nums):
cacu = cacu * x
while k <= cacu and left <= right:
cacu = cacu/nums[left]
left +=1
ans += right -left +1
return ans
第四题:与第二题相似,我们需要借用到counter()去存储内容。只需要更改一个条件就行了

代码:
python
class Solution:
def maximumLengthSubstring(self, s: str) -> int:
left = 0
cnt =Counter()
ans = 0
for right ,x in enumerate(s):
cnt[x] +=1
while cnt[x]>2:
cnt[s[left]]-=1
left +=1
ans = max(ans,right -left +1)
return ans
第五题:跟上面的和不超过多少的子数组如出一辙,都是用同向的方法就可以解决

python
class Solution:
def maxSubarrayLength(self, nums: List[int], k: int) -> int:
left =0
res = 0
cnt = Counter()
for right, x in enumerate(nums):
cnt[x] +=1
while cnt[x] > k :
cnt[nums[left]] -=1
left +=1
res = max(res,right-left+1)
return res
第六题:这题还是有点绕,主要是那个same的逻辑需要搞清楚。

python
class Solution:
def longestSemiRepetitiveSubstring(self, s: str) -> int:
ans , left,same = 1,0,0
for right in range(1,len(s)):
same +=s[right] ==s[right-1]
if same >1:
left+=1
while s[left]!= s[left-1]:
left+=1
same =1
ans =max(ans,right -left+1)
return ans
第七题:

也是看了题解才写出来的,虽然是很标准的同向双指针,但是还是有点困难。
python
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
res =0
left =0
cnt = 0
for right in range(len(nums)):
cnt += 1-nums[right]
while cnt >k:
cnt -= 1-nums[left]
left +=1
res = max(res,right-left+1)
return res
第8题:这题可不简单,虽然他的代码很简单,但是其实已经包含了很多的内容,其中最为关键的是ans += left这个处理的理解,当我们不理解的时候,只觉得他是很简单的一行代码,他其实是一个完备的解的相加

python
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
mx = max(nums)
left = ans = cnt = 0
for x in nums:
if mx==x:
cnt +=1
while cnt ==k:
if nums[left]==mx:
cnt -=1
left +=1
ans += left
return ans
第九题:这题不难,只需要写好内部的while循环就行了。当然其中的res也是需要想清楚的

python
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
total = 0
left = 0
res = 0
for right, x in enumerate(nums):
total +=x
while total *(right-left+1)>=k and left<=right:
total -= nums[left]
left+=1
res += right - left +1
return res
第十题:逆反思维,找最大的集合,然后就可以求出来了

用了一个哨兵,去判断是否修改过了
python
class Solution:
def minOperations(self, nums: List[int], x: int) -> int:
total = sum(nums)
left = 0
max_cnt =0
sb = 0
max_res = 0
for right,y in enumerate(nums):
max_cnt +=y
while max_cnt > total-x and left<=right:
max_cnt -=nums[left]
left +=1
if max_cnt== total-x:
max_res = max(max_res,right-left+1)
sb =1
return len(nums)-max_res if sb else -1
11题:没做出来。感觉逻辑没弄清楚

自己又麻木地写了一遍:
python
class Solution:
def minLength(self, nums: List[int], k: int) -> int:
cnt = Counter()
left = 0
ans = inf
s = 0
for right, x in enumerate(nums):
cnt[x] +=1
if cnt[x] ==1:
s +=x
while s>=k:
ans = min(ans,right-left+1)
if cnt[nums[left]] == 1:
s -= nums[left]
cnt[nums[left]] -=1
left +=1
return ans if ans<inf else -1
第12题:
道爷我成了,我独立解了一道难题,哇真的哭死。

python
class Solution:
def minWindow(self, s: str, t: str) -> str:
cnt_t = Counter()
cnt_s = Counter()
left =0
save_left =0
save_right =0
sm = inf
for i in t:
cnt_t[i] +=1
for right,x in enumerate(s):
cnt_s[x] +=1
while cnt_s>=cnt_t:
cnt_s[s[left]] -=1
if sm >right-left+1:
sm = right-left+1
save_left = left
save_right = right
left +=1
res =s[save_left:save_right+1]
return res if sm<inf else ""