LeetCode(力扣) 209题:和大于等于 target 的最短子数组----滑动窗口求解附带详细注释

题目描述
给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [ n u m s i nums_i numsi, n u m s i + 1 nums_{i+1} numsi+1, …, n u m s r − 1 nums_{r-1} numsr1, n u m s r nums_r numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
输入:target = 4, nums = [1,4,4]
输出:1
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

思路分析
题意给定一个无需的容量为n的正整数数组和一个正整数target,要我们找出和大于等于target的最短子数组。因为是无序的,而且我们要找的是连续子数组,那么会比较自然的想到滑动窗口的方法。设定窗口的起点 left 和终点 right,逐步从数组左端滑动至右端,期间根据窗口覆盖子数组的和进行窗口大小的调整。假设此时窗口内的子数组和大于等于target,那么一直去除窗口起点的元素直到窗口内的元素和小于target,然后继续扩展窗口的终点,如此循环,直到窗口终点移动到数组最右端。

这么说可能比较抽象,大家看一下代码估计就能明白了。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        if sum(nums) < target:
            return 0
        ans = len(nums) #最终返回的结果
        res = 0 #滑动窗口覆盖子数组的和
        #题意要求找到和>=target的最短连续子数组
        #首先想到使用滑动窗口的方法解决问题
        l, r = 0, 0 #定义窗口的起点和终点
        while r < len(nums):
        	#窗口终点向右滑动
            res += nums[r]
            #如果窗口覆盖子数组的值>=target, 调整窗口起点的位置 
            while res >= target:
                ans = min(ans, r - l + 1)
                res -= nums[l]
                l += 1
            #窗口起点调整好之后,继续向前移动
            r += 1
        return ans

程序运行结果
在这里插入图片描述
可以看到,代码的效率还是很高的。

总结
做过一部分数组的题之后,发现数组的题目大多可以用二分查找、双指针、动态规划等方法解决,根据具体题目选择具体的方法即可,要学会从题意中抽象出数学模型,再做决策。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值