力扣滑动窗口小结

一、最小覆盖子串

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值