leetcode第八百六十二题—和至少为K的最短子数组

这道题有点意思,双指针思路有了,但是情况考虑不全了,还需要加强。

1.题目

原题

返回 A 的最短的非空连续子数组的长度,该子数组的和至少为 K 。如果没有和至少为 K 的非空子数组,返回 -1 。

例子

输入:A = [2,-1,2], K = 3
输出:3

2.解析

思路1:双指针,start,end分别指向0,为啥指向0,是因为担心有一个元素的数组被遗漏。然后用两层while循环实现一个复杂度为O(N)的算法,但是这次遇到的问题是遇到包括负数的数组就是不行了,这个需要做个判断,思路比较复杂,暂时不想了,直接给出适合全为正数数组的算法。
思路2:双向对列法,本质也是一个双指针,延续了和为K系列题的一贯解法,就是要维护一个到i位置的累积和,然后数组区间就是和相减。
要维护一个双向对列,这里需要满足两个性质,具体解释可以看官网,觉得不如双指针好用,但是确实可以方便解决问题。

3.python代码

##双指针法
class Solution:
    def shortestSubarray(self, A, K):
        m = len(A)
        start, end = 0, 0
        tmpsum = 0
        minlen = 100000000000000
        while start < m and end < m:
            while tmpsum + A[end] >= K and start < m:
                print(start, end)
                tmpsum -= A[start]
                minlen = min(minlen, end-start+1)
                start += 1
            tmpsum += A[end]
            end += 1
        return [-1 if minlen == 100000000000000 else minlen][0]
##双向队列法
    def shortestSubarray(self, A, K):
        m = len(A)
        ans = m + 1
        P = [0]
        for x in A:
            P.append(P[-1]+x)
        mon = collections.deque()
        for y, ys in enumerate(P):
            while mon and ys <= P[mon[-1]]:
                mon.pop()
            while mon and ys - P[mon[0]] >= K:
                ans = min(ans, y - mon.popleft())
            mon.append(y)
        return -1 if ans > m else ans

你可能感兴趣的:(leetcode第八百六十二题—和至少为K的最短子数组)