leetcode第八百六十二题—和至少为K的最短子数组
2020-03-15 本文已影响0人
不分享的知识毫无意义
这道题有点意思,双指针思路有了,但是情况考虑不全了,还需要加强。
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