zoukankan      html  css  js  c++  java
  • 【leetcode】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).

    解题思路:本题如果只要求求出三段子数组的和的最大值,那会简单很多。记total[i]为arr[i:i+k]段的和,dp_left_max[i]为nums[:i]区间内长度为k的子数组的和的最大值,dp_right_max[i]为nums[i:len(nums)]区间内长度为k的子数组的和的最大值,很显然如果中间段的子数组的下标为k,那么可以得到三段和的最大长度的表达:total[i] + dp_left_max[i-k] + dp_right_max[i+k] 。只要遍历数组arr,即可求出最大值。求出后就是计算出左边以及右边最大值出现时的最小下标,这个可以通过二分查找实现。

    代码如下:

    class Solution(object):
        def maxSumOfThreeSubarrays(self, nums, k):
            """
            :type nums: List[int]
            :type k: int
            :rtype: List[int]
            """
            count = sum(nums[:k])
            total = [count]
            total_inx = {}
            total_inx[count] = [0]
            dp_left_max = [count]
            dp_left_max_count = count
            for i in range(k, len(nums)):
                count -= nums[i - k]
                count += nums[i]
                total += [count]
                total_inx[count] = total_inx.setdefault(count,[]) + [i-k + 1]
                dp_left_max_count = max(dp_left_max_count,count)
                dp_left_max.append(dp_left_max_count)
    
            reverse_num = nums[::-1]
            count = sum(reverse_num[:k])
            dp_right_max = [count]
            dp_right_max_count = count
            for i in range(k, len(reverse_num)):
                count -= reverse_num[i - k]
                count += reverse_num[i]
                dp_right_max_count = max(dp_right_max_count,count)
                dp_right_max.insert(0,dp_right_max_count)
    
    
            #print total
            #print total_inx
            #print dp_left_max
            #print dp_right_max
    
            max_sum = -float('inf')
            mid_inx = 0
            left_val = 0
            right_val = 0
            for i in range(k,len(nums)-k-k+1):
                count = total[i] + dp_left_max[i-k] + dp_right_max[i+k]
                if count > max_sum:
                    mid_inx = i
                    left_val = dp_left_max[i-k]
                    right_val = dp_right_max[i+k]
                    max_sum = count
            #print left_val,mid_inx,right_val
    
            left_inx = total_inx[left_val][0]
            import bisect
            right_inx = bisect.bisect_left(total_inx[right_val],mid_inx+k)
            return [left_inx,mid_inx,total_inx[right_val][right_inx]]
  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/seyjs/p/11616699.html
Copyright © 2011-2022 走看看