leetcode.数组滑动窗口209/904/76

其实滑动窗口就是变相的双指针,不停加入right
达到“条件”后开始缩减窗口(移动left),打擂台挑出正确值

lc.209长度最小的子数组

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left = 0
        right = 0
        window_sum = 0
        min_len = float('inf')

        while right < len(nums):
            #无脑加入right
            window_sum += nums[right]

            #达到收割结果条件
            while window_sum >= target:
                min_len = min(min_len, right - left + 1)
                window_sum -= nums[left]
                left += 1

            #开始加入下一个right
            right += 1

        if min_len == float('inf'):
            return 0
        return min_len

lc.904水果成篮

使用Counter记录每个果子的数量
此题和lc209的区别在于,我们达到条件的部分在下方
内部的while用于处理超出题目条件的情况
因此下方的left和right一定满足了题目条件

1、无脑添加right

2、不收割,调整window使得符合条件

3、收割

4、添加下一个right

class Solution:
    from collections import Counter
    def totalFruit(self, fruits: List[int]) -> int:
        left = 0
        right = 0
        max_len = float('-inf')
        my_dict = Counter()

        while right < len(fruits):
            #无脑加入right
            my_dict[fruits[right]] += 1

            #这里不收割,而是处理掉不满足题目条件的情况
            while len(my_dict) > 2:
                my_dict[fruits[left]] -= 1
                if my_dict[fruits[left]] == 0:
                    my_dict.pop(fruits[left])
                left += 1
            
            #上方while处理了,这里就一定满足题目条件了
            max_len = max(max_len, right - left + 1)
            #开始加入下一个right
            right += 1
        
        return max_len

lc.76最小覆盖子串

还是按照我总结的模版:

1、无脑添加right(扩张window)

2、收割并尝试移动left(收缩window)

3、添加下一个right

class Solution:
    from collections import Counter
    from collections import deque
    def minWindow(self, s: str, t: str) -> str:
        left = 0
        right = 0
        min_len = float('inf')
        min_left = 0
        t_dict = Counter(t)
        s_dict = Counter()
        while right < len(s):
            #无脑添加right
            s_dict[s[right]] += 1

            #符合条件收割
            while all(s_dict[char] >= t_dict[char] for char in t_dict.keys()):
                sub_len = right - left + 1
                #记录最小长度和其左开头index
                if sub_len < min_len:
                    min_len = sub_len
                    min_left = left
                #缩小滑动窗口
                s_dict[s[left]] -= 1
                left += 1
            
            #添加下一个right
            right += 1
        if min_len == float('inf'):
            return ""
        res = s[min_left:min_left + min_len]
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值