滑动窗口

76. 最小覆盖子串

3. 无重复字符的最长子串

1004. 最大连续1的个数 III

1052. 爱生气的书店老板

1438. 绝对差不超过限制的最长连续子数组

1423. 可获得的最大点数

76. 最小覆盖子串

1.构建一个滑动窗口，左右指针怎么移动？右指针移动：当窗口内的内容不满足条件 左指针：当窗口内的指针满足条件

class Solution:
def minWindow(self, s: 'str', t: 'str') -> 'str':
t=collections.Counter(t)
lookup=collections.defaultdict(int)
minLen=float('inf')
res=""
l=r=0
while r<len(s):
lookup[s[r]]+=1
r+=1
while all(map(lambda x:lookup[x]>=t[x],t.keys())):
if r-l<minLen:
res=s[l:r]
minLen=r-l
lookup[s[l]]-=1
l+=1
return res

class Solution:
def minWindow(self, s: 'str', t: 'str') -> 'str':
lookup=collections.defaultdict(int)
for i in t:lookup[i]+=1
count=len(t)
l=r=0
min_len=float('inf')
res=""
while r<len(s):
if lookup[s[r]]>0:count-=1
lookup[s[r]]-=1
r+=1
while count==0:
if min_len>r-l:
min_len=r-l
res=s[l:r]
if lookup[s[l]]==0:count+=1
lookup[s[l]]+=1
l+=1
return res



3. 无重复字符的最长子串

1.双指针+hash

class Solution:
def lengthOfLongestSubstring(self, s):
lookup=collections.defaultdict(int)
res=0
l=r=0
count=0
while r<len(s):
if lookup[s[r]]>0:count+=1#这个字符前面出现过
lookup[s[r]]+=1
r+=1
while count>0:
if lookup[s[l]]>1:count-=1
lookup[s[l]]-=1
l+=1
res=max(res,r-l)
return res

class Solution(object):
def lengthOfLongestSubstring(self, s):
if not s:return 0
l=r=0
res=0
h={}
while r<len(s):
if s[r] in h:
l=max(l,h[s[r]])
res=max(res,r-l+1)
h[s[r]]=r+1
r+=1
return res



1004. 最大连续1的个数 III

[1,1,1,0,0,1,1,1,1,1,1]

1.直接暴力o(n³)

2.sum优化成前缀和暴力o(n²)

3.滑动窗口，右指针一直右走，左指针当窗口内的0的个数>k时右走

class Solution:
def longestOnes(self, A: List[int], K: int) -> int:
if K>=A.count(0):return len(A)
res=0
for i in range(len(A)):
for j in range(i+1,len(A)):
if j-i+1-sum(A[i:j+1])==K:
res=max(res,sum(A[i:j+1])+K)
return res

class Solution:
def longestOnes(self, A: List[int], K: int) -> int:
if K>=A.count(0):return len(A)
res=0
pre=[0 for _ in range(len(A))]
pre[0]=A[0]
for i in range(1,len(A)):
pre[i]=pre[i-1]+A[i]
for i in range(len(A)):
for j in range(i+1,len(A)):
if i-1>=0:sum_=pre[j]-pre[i-1]
else:sum_=pre[j]
if j-i+1-sum_==K:
res=max(res,sum_+K)
return res

class Solution:
def longestOnes(self, A: List[int], K: int) -> int:
if K>=len(A):return len(A)
l=r=0
res=0
count=0
while r<len(A):
if A[r]==0:count+=1
while count>K:
if A[l]==0:count-=1
l+=1
res=max(res,r-l+1)
r+=1
return res


1052. 爱生气的书店老板

1.暴力直接枚举grumpy数组连续的x个数为0的情况

2.滑动窗口

class Solution:
def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int:
res=0
def func(index):
ans=0
for i in range(len(customers)):
if grumpy[i]==0 or index<=i<=index+X-1:
ans+=customers[i]
return ans

for i in range(len(grumpy)-X+1):
res=max(res,func(i))
return res

class Solution:
def maxSatisfied(self, customers: List[int], grumpy: List[int], X: int) -> int:
res1=0
for i in range(len(customers)):
if grumpy[i]==0:
res1+=customers[i]
customers[i]=0
l=0
r=X-1
tmp_sum=sum(customers[:X])
res2=tmp_sum
while r<len(customers):
r+=1
if r>len(customers)-1:break
tmp_sum+=customers[r]
tmp_sum-=customers[l]
l+=1
res2=max(res2,tmp_sum)

return res1+res2



["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]

1.用普通队列实现，max_value用暴力获取其值

2.用一个辅助队列

class MaxQueue:

def __init__(self):
self.q=collections.deque()

def max_value(self) -> int:
return max(self.q) if self.q else -1

def push_back(self, value: int) -> None:
self.q.append(value)

def pop_front(self) -> int:
return self.q.popleft() if self.q else -1

class MaxQueue(object):

def __init__(self):
self.q=collections.deque()
self.q_keep=collections.deque()

def max_value(self):
return self.q_keep[0] if self.q_keep else -1

def push_back(self, value):
self.q.append(value)
while self.q_keep and self.q_keep[-1]<value:
self.q_keep.pop()
self.q_keep.append(value)

def pop_front(self):
if not self.q:return -1
res=self.q.popleft()
if res==self.q_keep[0]:self.q_keep.popleft()
return res



1438. 绝对差不超过限制的最长连续子数组

1.很好的题，滑动窗口(一般求子串，子区间问题可以考虑)，滑动窗口问题需要考虑2个指针怎么移动，r指针可以走的话一直往右走，左指针当窗口内容不满足条件时往左走，这里的条件就是窗口内的max_value-min_value<=limit，这里就涉及到另一个知识点，怎么用o(1)的时间获得当前区间的最值？单调队列！，维护2个单调队列！

class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
q_max=[]
q_min=[]
res=0
l=r=0
while r<len(nums):
while q_max and nums[r]>nums[q_max[-1]]:
q_max.pop()
q_max.append(r)
while q_min and nums[r]<nums[q_min[-1]]:
q_min.pop()
q_min.append(r)
while q_min and q_max and nums[q_max[0]]-nums[q_min[0]]>limit:
if q_max[0]<=l:q_max.pop(0)
if q_min[0]<=l:q_min.pop(0)
l+=1
res=max(res,r-l+1)
r+=1
return res

1423. 可获得的最大点数

1.贪心+前缀和

2.dfs直接左右2种情况搜索，超时

3.滑动窗口

class Solution:
def maxScore(self, cardPoints: List[int], k: int) -> int:
n=len(cardPoints)
left=[0 for _ in range(n+1)]
right=[0 for _ in range(n+1)]
for i in range(n):
left[i+1]=left[i]+cardPoints[i]
right[i+1]=right[i]+cardPoints[n-i-1]
res=0
l=r=0
u=k
for i in range(k):
if left[l+u]-left[l]>right[r+u]-right[r]:
res+=cardPoints[l]
print("left",cardPoints[l])
l+=1
else:
res+=cardPoints[n-r-1]
print("right",cardPoints[r])
r+=1
u-=1
return res

class Solution:
def maxScore(self, cardPoints: List[int], k: int) -> int:
if k==len(cardPoints):return sum(cardPoints)
def dfs(l,r,k):
if k==1:return max(cardPoints[l],cardPoints[r])
return max(dfs(l+1,r,k-1)+cardPoints[l],dfs(l,r-1,k-1)+cardPoints[r])
return dfs(0,len(cardPoints)-1,k)

05-14 5248

03-23 3万+

04-23 2万+

02-25 2167

05-17 1124

11-01 3022

02-13 88

04-14 754

03-07 629

12-12 284

02-20 843

02-13 49

03-12 48

08-24 47

03-19 83万+

04-14 62万+

03-13 16万+

03-01 14万+

03-08 5万+

03-10 14万+

副业收入是我做程序媛的3倍，工作外的B面人生是怎样的？

©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客