作者: 负雪明烛
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. 关于SQL中Union和Join的用法

    转自帘卷西风的专栏(http://blog.csdn.net/ljxfblog) https://blog.csdn.net/ljxfblog/article/details/52066006 Uni ...

  2. 零基础学习java------38---------spring中关于通知类型的补充,springmvc,springmvc入门程序,访问保护资源,参数的绑定(简单数据类型,POJO,包装类),返回数据类型,三大组件,注解

    一. 通知类型 spring aop通知(advice)分成五类: (1)前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常. (2)正常返回通知 ...

  3. 使用 Addressables 来管理资源

    使用 Addressables 来管理资源 一.安装 打开Package Manager,在Unity Technologies的目录下找到Addressables,更新或下载. 二.配置 依次打开W ...

  4. Android 开源框架Universal-Image-Loader加载https图片

    解决方案就是 需要 android https HttpsURLConnection 这个类忽略证书 1,找到 Universal-Image-Loader的library依赖包下面com.nostr ...

  5. Output of C++ Program | Set 8

    Predict the output of following C++ programs. Question 1 1 #include<iostream> 2 using namespac ...

  6. mysql锁相关讲解及其应用

    一.mysql的锁类型 了解Mysql的表级锁 了解Mysql的行级锁 (1) 共享/排它锁(Shared and Exclusive Locks) 共享锁和排他锁是InnoDB引擎实现的标准行级别锁 ...

  7. 【Python】【Basic】【数据类型】基本数据类型

    1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位系统上,整数的位数为64位,取值范围为-2 ...

  8. mysql与clickhouse的字段类型对应表

  9. 【Linux】【Services】【SaaS】Docker+kubernetes(2. 配置NTP服务chrony)

    1. 简介 1.1. 这次使用另外一个轻量级的NTP服务,chrony.这是openstack推荐使用的ntp服务. 1.2. 官方网站:https://chrony.tuxfamily.org/ 2 ...

  10. Appium获取toast消息遇到的问题(一)

    一.运行错误 Android获取toast,需要在参数里设置automationName:Uiautomator2 1 # 设置设备的信息 2 desired_caps = { 3 'platform ...