Leetcode刷题笔记 - 数组(滑动窗口法)

滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果的方法,一般来说可以通过一个for循达到滑动的目的,for循环的索引一般表示的是滑动窗口的终止位置

Leetcode209 长度最小的子数组

【题目描述】

【可用方法】

1.方法一:暴力枚举

定义两层for循环,第一层先遍历数组,更新子数组的起始位置,第二层从起始位置开始遍历数组,将所遍历的子数组求和,当当前和大于等于s时,更新最小子串长度(最小字串默认设置为数组长度+1),剪枝,最后判断最小长度是否为初始值,若是则代表没有找到满足条件的子数组,则返回0,否则返回最小长度

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        res = len(nums)+1
        for i in range(len(nums)):
            cur_sum = 0
            for j in range(i,len(nums)):
                cur_sum = cur_sum + nums[j]
                if cur_sum >= target:
                    res = min(res,j-i+1)
                    break
        if res == len(nums)+1:
            return 0
        else:
            return res

2.方法二:滑动窗口

此题中,i,j默认设置为0,分别表示数组的起始位置和终止位置,对终止位置进行遍历,找到数组中第一个满足条件的子数组,并记录其长度,然后通过减去起始位置并更新其实位置索引,试图寻找当前位置下是否有更短的字符串,如果有更新长度,继续更新起始位置,如果没有,更新终止位置继续查找

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        if nums == None or len(nums)==0:
            return 0
        res = len(nums) + 1
        total = 0
        i = 0
        j = 0
        while j < len(nums):
            total = total + nums[j]
            j = j + 1
            while total >= target:
                res = min(res,j-i)
                total = total - nums[i]
                i = i + 1
        if res == len(nums) + 1:
            return 0
        else:
            return res

【相关题目】

904 水果成篮

76 最小覆盖子串


Leetcode904 水果成篮

【题目描述】

 【可用方法】

1.方法一:暴力枚举

超时

2.方法二:滑动窗口

定义cnt为colleections模块下的字典,然后起始位置和终止位置分别为left,right,最大收集数目默认为0,遍历数组更新终止位置,将水果的种类和数目分别作为key、value添加到字典中,记录最大收集数目,但一旦字典长度>2,则更新起始位置left,并更新字典直到某个键的值为0,此时删除该键值对,维护字典长度小于等于2,然后终止位置继续更新,记录最大收集数目

class Solution:
    def totalFruit(self, fruits: List[int]) -> int:
        cnt = collections.defaultdict(int)

        left = res = 0

        for right in range(len(fruits)):
            cnt[fruits[right]] += 1
            while len(cnt) > 2:
                cnt[fruits[left]] -= 1
                if cnt[fruits[left]] == 0:
                    cnt.pop(fruits[left])
                left += 1
            res = max(res,right - left + 1)
        return res

Leetcode76 最小覆盖子串

 【题目描述】

 【可用方法】

1.方法一:暴力枚举

待定

2.方法二:滑动窗口

class Solution:
    def minWindow(self, s: str, t: str) -> str:
        need_dict = collections.defaultdict(int)
        for ch in t:
            need_dict[ch] += 1
        need_cnt = len(t)

        i = 0
        j = 0
        res=[0,len(s)+1]
        for j in range(len(s)):
            if need_dict[s[j]] > 0:
                need_cnt -= 1
            need_dict[s[j]] -= 1
            if need_cnt == 0:
                while need_cnt == 0:
                    if res[1] - res[0] > j - i:
                        res = [i,j]
                    need_dict[s[i]] += 1
                    if s[i] in t and need_dict[s[i]]>0:
                        need_cnt += 1
                    i += 1
        return s[res[0]:res[1]+1] if res[1]-res[0] < len(s)+1 else ''

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值