作者: 负雪明烛
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. nginx_日志切割脚本

    #!/bin/bash NGINX_LOG=/usr/loca/nginx/logs/access.log RE_LOG=/data/backup/`data +%Y%m%d` echo -e &qu ...

  2. 学习java的第二十天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...

  3. 日常Java 2021/10/24

    Java ArrrayList ArrayList类是一个可以动态修改的数组,没有固定大小的限制,可以在任何时候添加或者删除元素 ArrayList类在java.util包中使用之前需要引用 E:泛型 ...

  4. 日常Java 2021/10/18

    Vecter类实现了一个动态数组,不同于ArrayList的是,Vecter是同步访问的, Vecter主要用在事先不知道数组的大小或可以改变大小的数组 Vecter类支持多种构造方法:Vecter( ...

  5. C++基本函数的调用优化(构造、拷贝构造、赋值)

    合理的函数可提升时间和空间的利用率 //Test1.h #include<iostream> using namespace std; struct ST { private: int a ...

  6. SpringAOP浅析

    1.问题 问题:想要添加日志记录.性能监控.安全监测 2.最初解决方案 2.1.最初解决方案 缺点:太多重复代码,且紧耦合 2.2.抽象类进行共性设计,子类进行个性设计,此处不讲解,缺点一荣俱荣,一损 ...

  7. 『学了就忘』Linux启动引导与修复 — 74、Linux系统的修复模式(光盘修复模式)

    目录 1.光盘修复模式概念 2.光盘修复模式修复系统问题 (1)准备系统光盘 (2)进入BIOS (3)修改BIOS的启动顺序 (4)进入光盘修复模式 (5)修复系统 (6)修复系统实操 (7)总结 ...

  8. 热部署详细步骤---·> 小热身!

    IDEA 2018.1.5 4版本 热部署 网址:https://www.jb51.net/softjc/629271.html

  9. Jenkins环境变量

    目录 一.环境变量 二.自定义环境变量 三.自定义全局变量 四.常用变量定义 五.常用环境变量 一.环境变量 环境变量可以被看作是pipeline与Jenkins交互的媒介.比如,可以在pipelin ...

  10. 学Java,Java书籍的最佳阅读顺序

    疫情以来,好久没出差了,今天出差去趟上海,早上 4 点多就起床了,到机场天都没亮.到登机口离起飞还一小时,趁着等飞机的时间,抓紧码字,把这篇文章收个尾. 今天和大家说说学 Java 的读书路线.路线中 ...