In a given array nums
of positive integers, find three non-overlapping subarrays with maximum sum.
Each subarray will be of size k
, and we want to maximize the sum of all 3*k
entries.
Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one.
Example:
Input: [1,2,1,2,6,7,5,1], 2 Output: [0, 3, 5] Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5]. We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger.
Note:
-
nums.length
will be between 1 and 20000. -
nums[i]
will be between 1 and 65535. -
k
will be between 1 and floor(nums.length / 3).
这题是FB最近的高频题,也是很经典的题目, 看到subarray的题目无非是dp或者two pointer的题目,但是这题看数组长度非常长,按普通区间DP或者3个pointer这种,复杂度为O(n^2),显然不合适。这题的解法充分利用了3个子数组这个条件,所以可以分开成左中右3个来考虑。用left[i]求0-i区间长度为k的最大和子数组的开始index,right[i] 求[i:len(nums)]区间内长度为k的最大和数组的开始index。之后我们针对中间数组,可以同步考虑左右边的情况,代码如下:
class Solution(object): def maxSumOfThreeSubarrays(self, nums, k): """ :type nums: List[int] :type k: int :rtype: List[int] """ # simplified version, left and right arrays have the same length with nums n = len(nums) if n < 3*k: return [] presum = [0]
presum[j] - presum[i] = sum(nums[i:j]) for i in nums: presum.append(presum[-1]+i) # left[i], from 0-i, largest sum subarray of length k‘s start index left = [0] * n # right[i], from i-n, largest sum subarray of length k‘s start index right = [n-k] * n for i in xrange(k-1, n-2*k): if i == k-1: maxsum = presum[i+1] - presum[0] left[i] = 0 else: if presum[i+1] - presum[i-k+1] > maxsum: maxsum = presum[i+1] - presum[i-k+1] left[i] = i - k + 1 else: left[i] = left[i-1] for i in xrange(n-k, 2*k-1, -1): if i == n-k: maxsum = presum[n] - presum[n-k] right[i] = n - k else: if presum[i+k] - presum[i] > maxsum: maxsum = presum[i+k] - presum[i] right[i] = i else: right[i] = right[i+1] res = [] maxsum = 0 for i in xrange(k, n-2*k+1): l = left[i-1] r= right[i+k] if presum[i+k] - presum[i] + presum[l+k] - presum[l] + presum[r+k] - presum[r] > maxsum: maxsum = presum[i+k] - presum[i] + presum[l+k] - presum[l] + presum[r+k] - presum[r] res = [l, i, r] return res
注意这里为了方便left和right都取成了和nums一样的长度,但是只有其中一部分有意义。