leetcode862. 和至少为 K 的最短子数组

参考:https://leetcode.cn/problems/shortest-subarray-with-sum-at-least-k/solution/liang-zhang-tu-miao-dong-dan-diao-dui-li-9fvh/
由于数组里可能存在负数,所以无法使用双指针
计算数组的前缀和,

def shortestSubarray(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        res = len(nums) + 1
        presum = [0]
        for i in nums:
            presum.append(presum[-1]+i)
        queue = collections.deque()
        for i,num in enumerate(presum):
            while queue and num - presum[queue[0]] >= k:   #注意这里是前缀和相减,代表这一段数组和。如果这一段的和大于等于k说明找到了以queue[0]开头的最短的序列。注意queue[0]是下标
                res = min(res,i-queue.popleft())
            while queue and presum[queue[-1]] >= num:  #如果前缀和的前一个元素比当前元素大,肯定后面这个元素的最短子序列短,所以前面的那个从队列弹出。这样同时保证了队列的单调性
                queue.pop()
            queue.append(i)
        return res if res <= len(nums) else -1

你可能感兴趣的:(前缀和,算法,数据结构)