前缀和-长度最小的子数组 python

题目链接:209. 长度最小的子数组 - 力扣(LeetCode) 

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

一 超时的做法 

思路见注释,滑动窗口的思想是正确的,但是中间的判断方式太复杂

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 滑动窗口来解决这个问题
        # 窗口前端,窗口后端,最小长度
        # 当窗口中所有数的总和 >= 目标值:与最小长度比较更新最小长度
        #  从前端开始剔除值直至小于目标值。
        # 当窗口中的数小于目标值,后端向后移动直至大于等于目标值
        # 当第一次找到时(前端为0)直接替换最小长度的值,不然最小长度一直是0
        head = 0
        tail = 0
        min_length = 0
        n = len(nums)
        while tail<n:
            if sum(nums[head:tail+1]) >= target:
                while sum(nums[head:tail+1]) >= target:
                    if head == 0:min_length = tail - head + 1
                    else:
                        min_length = min(tail-head+1, min_length)
                    head+=1
            else:
                tail+=1
        return min_length
        

二  合格的做法

思路没变,判断条件改变,选用一个变量total来表示滑动窗口中的总值,而不是使用sum()

节省了大量时间,最小长度 的初始值也做出了变化,减少了判断次数。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 滑动窗口来解决这个问题
        # 窗口前端,窗口后端,最小长度
        # 当窗口中所有数的总和 >= 目标值:与最小长度比较更新最小长度
        #  从前端开始剔除值直至小于目标值。
        # 当窗口中的数小于目标值,后端向后移动直至大于等于目标值
        # 开始时设置 最小值为列表长度 +1(往后出现的任何一种符合的情况都可以跟他替换)
        # 到最后如果发现最小长度仍为 列表长度+1,证明不存在符合的情况
        head = 0
        tail = 0
        total = 0
        n = len(nums)
        min_length = n + 1 
        while tail<n:
            total += nums[tail]
            while total >= target:
                min_length = min(tail - head + 1, min_length)
                total -= nums[head]
                head += 1
            tail += 1
        return 0 if min_length == n+1 else min_length
        

 

三 总结

滑动窗口内的元素数量大时,不要使用聚合函数进行条件的判断

而是选择变量暂存结果,能节省大量聚合函数的执行时间 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值