作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址: https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/description/

题目描述:

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:

  1. nums.length will be between 1 and 20000.
  2. nums[i] will be between 1 and 65535.
  3. k will be between 1 and floor(nums.length / 3).

题目大意

把一个很长的数组,分成三个不重叠的子数组,要求每个子数组的长度都必须是k,最后的目的是三个子数组的和最大。

解题方法

看题目的数据知道需要用O(N)的解法,另外优化最值问题一般都是DP。具体怎么做呢?

把三个数组分别看做左侧,中间,右侧的数组。我们指定了中间数组的位置之后,就在这个位置左侧和右侧分别求一个和最大的子数组,然后三个数组和相加,就得到了总体最大的和。

使用sums数组保存到每个位置的累积和。这样做的好处是我们可以直接根据两个位置相减求出子数组的和。另外需要两个DP数组left和right。

left[i]表示在区间[0, i]范围内长度为k且和最大的子数组的起始位置

right[i]表示在区间[i, n - 1]范围内长度为k且和最大的子数组的起始位置

left的求法是从左到右遍历,right的求法是从右到左遍历。遍历刚开始的K个位置内由于子数组长度小于k,所以left的值是0,right的值是N - k,代表的是能取子区间的边缘情况下索引。更新过程也不难,就是和已有的子数组最大和比较,然后更新索引位置就行了。

求出了每个位置左边和右边的长度为k的子数组之后,需要再次用一个窗口遍历数组,这个窗口就是我们中间的数组。这就成为了在确定中间数组位置的情况下,左边和右边的最大数组和问题,因为我们已经知道了left和right,那么就相当于查表得到位置。

这个题对sums是添加了头部0的,这样的好处是求到目前为止的和的时候可以直接从nums第0个数组开始找前面一个sums+当前的数字。

这个题最难的地方应该在于铺天盖地的索引值吧……反正我是被搞晕了。

时间复杂度是O(N),空间复杂度是O(N)。

class Solution(object):
def maxSumOfThreeSubarrays(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
N = len(nums)
sums = [0]
left = [0] * N
right = [N - k] * N
mx = 0
res = [0, 0, 0]
for i, num in enumerate(nums):
sums.append(sums[-1] + num)
total = sums[k] - sums[0]
for i in range(k, N):
if sums[i + 1] - sums[i - k + 1] > total:
left[i] = i - k + 1
total = sums[i + 1] - sums[i - k + 1]
else:
left[i] = left[i - 1]
total = sums[N] - sums[N - k]
for j in range(N - k - 1, -1, -1):
if sums[j + k] - sums[j] >= total:
right[j] = j
total = sums[j + k] - sums[j]
else:
right[j] = right[j + 1]
for i in range(k, N - 2 * k + 1):
l, r = left[i - 1], right[i + k]
total = (sums[i + k] - sums[i]) + (sums[l + k] - sums[l]) + (sums[r + k] - sums[r])
if total > mx:
mx = max(mx, total)
res = [l, i, r]
return res

参考资料:

https://www.cnblogs.com/grandyang/p/8453386.html

日期

2018 年 10 月 5 日 —— 转眼假期要结束了!!

【LeetCode】689. Maximum Sum of 3 Non-Overlapping Subarrays 解题报告(Python)的更多相关文章

  1. LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays

    原题链接在这里:https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/ 题目: In a given arr ...

  2. [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. E ...

  3. [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. E ...

  4. 【LeetCode】985. Sum of Even Numbers After Queries 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 找规律 日期 题目地址:https://lee ...

  5. LeetCode 653 Two Sum IV - Input is a BST 解题报告

    题目要求 Given a Binary Search Tree and a target number, return true if there exist two elements in the ...

  6. 【LeetCode】107. Binary Tree Level Order Traversal II 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:迭代 日期 [LeetCode ...

  7. 【LeetCode】1019. Next Greater Node In Linked List 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 单调递减栈 日期 题目地址:https://leetc ...

  8. 【LeetCode】82. Remove Duplicates from Sorted List II 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/remove-du ...

  9. 【LeetCode】373. Find K Pairs with Smallest Sums 解题报告(Python)

    [LeetCode]373. Find K Pairs with Smallest Sums 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/p ...

  10. 【LeetCode】375. Guess Number Higher or Lower II 解题报告(Python)

    [LeetCode]375. Guess Number Higher or Lower II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

随机推荐

  1. 搭建简单的SpringCloud项目三:问题及解决

    GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 搭建简单的SpringCloud项目二:服务 ...

  2. How To Call An Ambulance

    How to Talk to the Emergency Dispatcher [minutesmatter.upmc稻糠亩] How To Call An Ambulance [askambulan ...

  3. 在idea的java开发中字符串length()方法获取长度与赋值不符的问题

    最近在开发中用到length()方法获取中文字符串的长度,发现获得的长度与实际不符.比如个String类型赋值为"中",但获取长度却是2. 这让我百思不得其解,后来突然想起来我在研 ...

  4. Sharding-JDBC 实现垂直分库水平分表

    1.需求分析

  5. 利用python爬取城市公交站点

    利用python爬取城市公交站点 页面分析 https://guiyang.8684.cn/line1 爬虫 我们利用requests请求,利用BeautifulSoup来解析,获取我们的站点数据.得 ...

  6. Spring(2):依赖注入DI

    依赖注入DI 当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例.但在Spring里,创建被 ...

  7. Spring 与 SpringBoot 的区别

    概述 Spring 与 SpringBoot 有什么区别???梳理一下 Spring 和 SpringBoot 到底有什么区别,从 Spring 和 SpringBoot 两方面入手. Spring ...

  8. Java Bean 与Spring Bean 的区别

    什么是JavaBean: JavaBean是一种JAVA语言写的可重用组件.JavaBean符合一定规范写的Java类,是一种规范.它的方法命名,构造以及行为必须符合特定的要求:     1.所有属性 ...

  9. 使用递归方法,遍历输出以.java结尾的文件

    package cn.itcast.demo01;import java.io.File;/** * @author newcityman * @date 2019/7/27 - 19:17 * 题目 ...

  10. 测试JDBCUtils的重用性

    package cn.itcast.jdbc;import cn.itcast.util.JDBCUtils;import java.sql.*;import java.util.Properties ...