📜  最小大小的子数组,其总和按非递增顺序递增(1)

📅  最后修改于: 2023-12-03 14:55:21.906000             🧑  作者: Mango

题目介绍

给定一个整数数组 nums 和一个整数 k,找出一个最小的连续子数组,使得该子数组中所有元素的和大于等于 k,返回该子数组的长度。如果不存在符合条件的子数组,则返回 -1。

此题要求子数组的总和按非递增顺序递增,即子数组的总和越小,子数组长度要越长。

解法

这道题我们可以用双指针解法来解决。双指针解法分别维护一个 left 和一个 right 指针,它们都从头开始。当区间和小于 k 时,我们将右指针右移,使得区间和增加,当区间和大于等于 k 时,我们记录下当前的最小区间长度,并将左指针右移,直到区间和小于 k 为止。

此时可以发现,我们右移右指针得到的子数组总是比左指针右移得到的子数组小,所以当右指针到达最右端时,如果还没有找到结果,那么左指针也不用再右移了。

代码实现

下面是使用 Python 语言实现的代码片段:

def smallestSubarray(nums: List[int], k: int) -> int:
    n = len(nums)
    left, right = 0, 0
    res = float('inf')
    total = 0

    while right < n:
        total += nums[right]
        while total >= k:
            res = min(res, right - left + 1)
            total -= nums[left]
            left += 1
        right += 1

    return -1 if res == float('inf') else res

代码中先求出数组的长度 n,然后初始化左指针和右指针为 0,结果 res 为正无穷,total 表示当前区间的元素总和。

当右指针小于 n 时,我们每次将右指针右移一位,并将右指针所对应的值加到 total 中。当 total 大于等于 k 时,则记录当前的最小区间长度,并将左指针右移,直到 total 小于 k。

最后,如果 res 仍为正无穷,则说明没有找到符合要求的子数组,返回 -1。否则返回 res。

总结

本题使用了常见的双指针解法,在理解该解法的基础上,可以很容易地写出代码。在实际应用中,该解法也经常被使用。