• leetcode689:Maximum Sum of 3 Non-Overlapping Subarrays


    给定数组a[N](每个元素都是正整数)和一个整数k(k小于等于N/3),要求从数组a中找出不相交的三个数组,每个数组长度都为k,使得三个数组之和最大。输出(i,j,k)表示三个子数组的开始下标,如果有多个答案,返回最小的那个三元组。

    分析:
    这个问题是前缀和的“花式玩法”,也可以看做是动态规划。
    定义数组s[N],s[i]表示sum(a[i-k+1]~a[i])
    定义数组ss[N],ss[i]表示sum(a[i-k+1]a[i])+max(s[0(i-k)]),也就是i前面的两个片段最大和,且第二个片段以i结尾。
    定义数组sss[N],sss[i]表示i前面的三个片段最大和,且第二个片段以i结尾。
    这个问题时空复杂度都为O(N)。

    这个问题还有一种简洁的解法,原因在于3的特殊性。
    什么是“三”,三就是左边一片,右边一片,中间一片。
    定义left数组,left[i]表示i左面最大的片段
    定义right数组,right[i]表示i右面最大的片段
    定义ans数组,ans[i]为中间一片、左边一片、右边一片之和,也就是ans[i]=s[i]+left[i-k]+right[i+1]

    任何事物,如果要想找到它的简便方法,就必须应用上这个事物的特殊性。

    class Solution:
        def maxSumOfThreeSubarrays(self, nums, k):
            """
            :type nums: List[int]
            :type k: int
            :rtype: List[int]
            """
            # print(nums)
            #前缀和
            s = [0] * len(nums)
            s[0] = nums[0]
            for i in range(1, len(s)):
                s[i] = s[i - 1] + nums[i]
    
            # print('s', s) 
            a = [0] * len(nums)
            a[k - 1] = s[k - 1]
            for i in range(k, len(s)):
                a[i] = s[i] - s[i - k]
            # print('a', a)
            #最大前缀和
            ss = [0] * len(nums)
            ma = 0
            for i in range(k - 1, len(s)):
                if a[i] > a[ma]:
                    ma = i
                ss[i] = (a[ma], ma)
            # print('ss',ss)
            sss = [0] * len(nums)
            for i in range(k * 2 - 1, len(s)):
                sss[i] = a[i] + ss[i - k][0]
            # print('sss',sss)
            #二级最大前缀和
            b = [0] * len(nums)
            ma = 0
            for i in range(k * 2 - 1, len(s)):
                if sss[i] > sss[ma]:
                    ma = i
                b[i] = (sss[ma], ma)
            # print('b',b)
            #三级前缀和
            c = [0] * len(nums)
            for i in range(k * 3 - 1, len(s)):
                c[i] = a[i] + b[i - k][0]
            # print('c',c)
            ans = 0
            for i in range(k * 3 - 1, len(c)):
                if c[i] > c[ans]:
                    ans = i
            ret = [0, 0, ans]
            ret[1] = b[ret[2] - k][1]
            ret[0] = ss[ret[1] - k][1]
            ret = list(map(lambda i: i - k+1, ret))
            return ret
    
    
    if __name__ == '__main__':
        ans = Solution().maxSumOfThreeSubarrays([1,2,1,2,6,7,5,1], 2)
        print(ans)
    
    
  • 相关阅读:
    Linux 资源监控整体分析-TOP
    GO基础之闭包
    GO基础之函数的高级用法
    GO基础之函数
    GO基础之流程控制语句
    数据结构导论(第二章线性表)
    JVM 参数配置
    GO基础之变量的使用
    数据结构导论(第一章概论)
    网络经济与企业管理(第11章:企业文化管理)
  • 原文地址:https://www.cnblogs.com/weiyinfu/p/7636061.html
Copyright © 2020-2023  润新知