【LeetCode刷题记录3】数组——滑动窗口

209. 长度最小的子数组

在这里插入图片描述

"""
暴力求解法 两个while循环。。时间复杂度到n2   可恶超时了
"""
class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        i, j = 0, 0 
        num = []
        if sum(nums) < target:
            return 0
        else:
            while i < len(nums):
                n = 0
                j = i
                while n < target and j <= len(nums)-1:
                    n += nums[j]
                    j = j + 1 
                if n >= target:
                    num.append(j-i)
                i += 1

        return min(num)
"""
时间复杂度为n的动态窗口法
"""
class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        i, j = 0, 0 
        num = []
        s = 0
        if sum(nums) < target:
            return 0
        else:
            while i < len(nums):
                s += nums[i]
                while s >= target and j <= i:
                    num.append(i-j+1)
                    s -= nums[j]
                    j+=1
                i += 1
        return min(num)

904. 水果成篮

在这里插入图片描述

class Solution(object):
    def totalFruit(self, fruits):
        """
        :type fruits: List[int]
        :rtype: int
        """
        j, l = 0, 0
        n = collections.Counter()
        for i in range(len(fruits)):
            n[fruits[i]] += 1
            while (len(n) > 2):
                n[fruits[j]] -= 1
                if not n[fruits[j]]:
                    n.pop(fruits[j])
                j += 1
            l = max(l, i - j + 1)
        return l

备注: 本质上求数组中,只包含两个不同元素的最长子字符串。这题结合哈希表做会简单,通过哈希表来控制左指针是否向右移动

76. 最小覆盖字串

在这里插入图片描述

class Solution(object):
    def minWindow(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: str
        """
        i, j, start, end = 0, 0, 0, 0
        nums = collections.Counter(t)
        l = len(s) + 1
        sumneed = len(t)

        while i < len(s):
                       
            if s[i] in t:
                if nums[s[i]] > 0:  # if nums[s[i]] > 0:  #这里要进行判断,只有当某个数的数量没满足要求的时候need才减1 需要注意的是当nums[s[i]]<0的时候,
                                     说明s[i]是多余的
                    sumneed -= 1
                nums[s[i]] -= 1

            while sumneed == 0 :  # 当满足要求的时候 第一步要先保存结果并比较 
                if i-j+1 < l:
                    start, end= j, i
                    l = i-j+1
                    
                if s[j] in t:      # 第二步要判断移动j 将导致哈希表出现什么样的变化
                    if nums[s[j]] >= 0: 
                        sumneed += 1
                    nums[s[j]] += 1
                j += 1
            i += 1
        
        if l == len(s) + 1:   
            return ""

        return s[start:end+1]

备注: 太难了。也是滑动窗口,重点是判断j移动的条件。

滑动窗口总结:

1、适合寻找数组中符合条件的连续子数组

2、一般用两个循环 外圈的while负责移动右指针,遍历更多的可能性。内圈的while判断左指针移动的条件,使得滑动窗口始终能满足题目条件

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值