zoukankan      html  css  js  c++  java
  • 689. Maximum Sum of 3 Non-Overlapping Subarrays

    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一样的长度,但是只有其中一部分有意义。

  • 相关阅读:
    音频波谱通用类|超酷的说
    跟随鼠标的星星实例
    AS3放大镜工具类
    caurina缓动类
    AS3中 is,as,typeof的区别
    Loader ,URLLoader ,URLStream的区别
    (转)AS3正则:元子符,元序列,标志,数量表达符
    动态绘制扇形实例
    AS3.0绘图API
    as3效率优化
  • 原文地址:https://www.cnblogs.com/sherylwang/p/9740066.html
Copyright © 2011-2022 走看看