862. Shortest Subarray with Sum at Least K

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. 1 <= A.length <= 50000
  2. -10 ^ 5 <= A[i] <= 10 ^ 5
  3. 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))


猜你喜欢

转载自blog.csdn.net/zjucor/article/details/80873206