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]]
  • 相关阅读:
    字体向上滚动
    地图改变图层
    移动地图
    [转] nodejs安装不了和npm安装失败的解决方法
    git回滚merge
    处理网站缓存问题
    webpack初学笔记 之 小案例篇demo1
    正则表达式整理
    关于返回值为图片 音频 视频的处理
    jquery ui datepicker 插件如何设置只能选择日期 禁止输入日期
  • 原文地址:https://www.cnblogs.com/seyjs/p/11616699.html
Copyright © 2011-2022 走看看