Return the length of the shortest, non-empty, contiguous subarray of A
with sum at least K
.
If there is no non-empty subarray with sum at least K
, return -1
.
Example 1:
Input: A = [1], K = 1 Output: 1
Example 2:
Input: A = [1,2], K = 4 Output: -1
Example 3:
Input: A = [2,-1,2], K = 3 Output: 3
Note:
1 <= A.length <= 50000
-10 ^ 5 <= A[i] <= 10 ^ 5
1 <= K <= 10 ^ 9
暴力O(N^2),最开始想照搬https://www.jianshu.com/p/17ede1f0a472 里面的思路,但是这里因为求得是最短的子数组,在由TreeMap1到TreeMap2转换的时候会出现解被覆盖的情况,比如runningSum[i]=A, runningSum[j]=A,但是可能就在i,j之间有最优解
所以要换个思路,对于每个以i结尾的子数组,有效的开头可能有很多;暴力的方法就是遍历每个有效的开头求最小的length,但是这些有效的开头都是有重叠的,一个优化的思路就是能不能每次不遍历所有有效开头,维护一个数据结构,每次都更新这个数据结构的value,从而避免重复运算
因为要求最短length,那就弄一个有序的数据结构,然后遍历每个结尾的index,对于每个index找一个位置使得子数组最短
from collections import deque
class Solution:
def shortestSubarray(self, a, k):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
n = len(a)
s = [0]*(n+1)
for i in range(n): s[i+1]=s[i]+a[i]
dq=deque()
res=n+1
for i,v in enumerate(s):
for j in range(len(dq)):
if s[dq[j]]>v-k: break
res=min(res, i-dq[j])
while dq and v<=s[dq[-1]]: dq.pop()
dq.append(i)
return res if res!=n+1 else -1
s=Solution()
print(s.shortestSubarray([2,-1,2], 3))
复杂度仍然N^2,可以优化,用二分来查找最短的res,或者直接pop掉,因为后面的index用不上(即使满足条件,但是不会比当前index结尾更短)
from collections import deque
class Solution:
def shortestSubarray(self, a, k):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
n = len(a)
s = [0]*(n+1)
for i in range(n): s[i+1]=s[i]+a[i]
dq=deque()
res=n+1
for i,v in enumerate(s):
while dq and s[dq[0]]<=v-k: res=min(res, i-dq.popleft())
while dq and v<=s[dq[-1]]: dq.pop()
dq.append(i)
return res if res!=n+1 else -1
s=Solution()
print(s.shortestSubarray([2,-1,2], 3))