一、最小覆盖子串
1、题目描述
2、题解:
class Solution:
def minWindow(self, s: str, t: str) -> str:
need,window = collections.defaultdict(int),collections.defaultdict(int)
for c in t:
need[c] += 1
# print(need)
left,right = 0,0
valid = 0
res,min_ ='', float('inf')
while right < len(s):
c = s[right]
right += 1
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1
while valid == len(need):
if right - left < min_:
res = s[left:right]
min_ = right - left
d = s[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
return res
3、复杂度分析:
时间复杂度:O(N+M)N,M分别为s和t的长度
空间复杂度:O(N)
二、字符串的排列
1、题目描述:
2、题解:
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
need,window = collections.defaultdict(int),collections.defaultdict(int)
for c in s1:
need[c] += 1
# print(len(need))
left,right = 0,0
valid = 0
while right < len(s2):
c = s2[right]
right += 1
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1
while right - left >= len(s1):
if valid == len(need):
return True
d = s2[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
# print(window)
return False
3、复杂度分析:
时间复杂度:O(N+M)
空间复杂度:O(N)
三、找到字符串中所有字母异位词
1、题目描述:
2、题解:
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
need,window = collections.defaultdict(int),collections.defaultdict(int)
for c in p:
need[c] += 1
left,right = 0,0
res,valid = [],0
while right < len(s):
c = s[right]
right += 1
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1
while right - left >= len(p):
if valid == len(need):
res.append(left)
d = s[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
return res
或者:
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
need,window = collections.defaultdict(int),collections.defaultdict(int)
for c in p:
need[c] += 1
left,right = 0,0
res,valid = [],0
while right < len(s):
c = s[right]
right += 1
if c in need:
window[c] += 1
if window[c] == need[c]:
valid += 1
while valid == len(need):
if right - left == len(p):
res.append(left)
d = s[left]
left += 1
if d in need:
if window[d] == need[d]:
valid -= 1
window[d] -= 1
return res
3、复杂度分析:
时间复杂度:O(N+M)
空间复杂度:O(N)
四、无重复字符的最长子串
1、题目描述:
2、题解:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
#滑动窗口
window = collections.defaultdict(int)
left,right = 0,0
res = 0
while right < len(s):
c = s[right]
right += 1
window[c] += 1
while window[c] > 1:
d = s[left]
left += 1
window[d] -= 1
res = max(res,right - left)
return res
或者:
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
#滑动窗口
window = []
left,right = 0,0
res = 0
while right < len(s):
c = s[right]
right += 1
while c in window:
d = s[left]
left += 1
window.pop(0)
window.append(c)
res = max(res,right - left)
return res
3、复杂度分析:
时间复杂度:O(N+M)
空间复杂度:O(N)
五、K 个不同整数的子数组
1、题目描述:
2、题解:
class Solution:
def subarraysWithKDistinct(self, A: List[int], K: int) -> int:
#滑动h窗口
if not A or len(A) < K:
return 0
window = collections.defaultdict(int)
left,right = 0,0
res = 0
valid = 0
temp = 1
while right < len(A):
c = A[right]
right += 1
window[c] += 1
if window[c] == 1:
valid += 1
while valid > K or window[A[left]] > 1:
if valid > K:
temp = 1
valid -= 1
else:
temp += 1
d = A[left]
left += 1
window[d] -= 1
if valid == K:
res += temp
return res
3、复杂度分析:
时间复杂度:O(N+M)
空间复杂度:O(N)
六、滑动窗口的最大值
1、题目描述:
2、题解:
方法1:排序
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
#排序
n =len(nums)
if k <= 0 or not nums or n < k:
return []
res = []
for i in range(n - k + 1 ):
res.append(sorted(nums[i:i+k])[-1])
return res
方法2:单调栈
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
#单调栈
# import collections
deque = collections.deque()
n = len(nums)
if k <= 0 or not nums or n < k:
return []
res = []
for i,j in zip(range(1-k,n-k +1),range(n)):
if i > 0 and deque[0] == nums[i-1]:
deque.popleft()
while deque and deque[-1] < nums[j]:
deque.pop()
deque.append(nums[j])
if i >= 0 :
res.append(deque[0])
return res
七、可获得的最大点数
1、题目描述:
2、题解:
class Solution:
def maxScore(self, cardPoints: List[int], k: int) -> int:
#前后共k的窗口大小
#先计算前k个窗口的大小
win,mx,lens = 0,0,len(cardPoints)
for i in range(k):
win += cardPoints[i]
#然后移动这个窗口,寻找最大值
mx = max(mx,win)
for i in range(k):
win -= cardPoints[k -i -1]
win += cardPoints[lens -1 -i]
mx = max(mx,win)
return mx
八、定长子串中元音的最大数目
1、题目描述:
2、题解:
class Solution:
def maxVowels(self, s: str, k: int) -> int:
res = 0
temp = {'a','e','i','o','u'}
if len(s) <= k:
for i in range(len(s)):
if s[i] in temp:
res += 1
return res
tlist = 0
for i in range(k):
if s[i] in temp:
tlist += 1
res = max(res,tlist)
right = k
while right < len(s):
if s[right - k] in temp and s[right] not in temp:
tlist -= 1
if s[right - k] not in temp and s[right] in temp:
tlist += 1
res = max(res,tlist)
right += 1
return res
九、绝对差不超过限制的最长连续子数组
1、题目描述:
2、题解:
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
l,r,res,ans = 0,0,[],0
while r < len(nums):
bisect.insort(res,nums[r])
while res[-1] - res[0] > limit:
res.remove(nums[l])
l += 1
r += 1
ans = max(ans,len(res))
return ans