LeetCode-689 三个无重叠子数组的最大和
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays
题目描述
给你一个整数数组 nums 和一个整数 k ,找出三个长度为 k 、互不重叠、且 3 * k 项的和最大的子数组,并返回这三个子数组。
以下标的数组形式返回结果,数组中的每一项分别指示每个子数组的起始位置(下标从 0 开始)。如果有多个结果,返回字典序最小的一个。
示例 1:
输入:nums = [1,2,1,2,6,7,5,1], k = 2
输出:[0,3,5]
解释:子数组 [1, 2], [2, 6], [7, 5] 对应的起始下标为 [0, 3, 5]。
也可以取 [2, 1], 但是结果 [1, 3, 5] 在字典序上更大。
示例 2:
输入:nums = [1,2,1,2,1,2,1,2,1], k = 2
输出:[0,2,4]
提示:
1 <= nums.length <= 2 * 104
1 <= nums[i] < 216
1 <= k <= floor(nums.length / 3)
解题思路
相信不少同学和我一样,看到题的第一反应就是这道题要用滑动窗口的方法来解。
最初的想法是使用贪心算法的思路,循环三次,每次找到没有被提取出来的子串中最大的那一个,但是做的过程中发现这样会破坏数组的顺序规律。比如nums = 1 6 8 7 7 1 8 1 k = 2的输入下,根据题意最终找出来的子串应该是,68 77 18,但是在贪心算法的思路下,就变成了87 18 16,出现这种情况的原因是用这种思路来找子串,仅仅考虑到了值最大这一条件,忽略了数字间的顺序关系。
于是产生了想法2.0,三个滑动窗口,同时进行滑动,分别记录每个窗口的和,如果三个窗口的和都是最大,那么总和一定是最大的,而由于三个窗口依次排列,所以理论上找出的子串应该都是可以保持顺序关系的,但是这种想法和第一种方法一样,找到最大值后会导致窗口停下,还是只考虑到局部最大,并没有考虑整体最大,并且,还可能三个窗口产生重叠。在更新一个窗口的时候,必须维护其他窗口,必须保证前窗口的尾部在后窗口的头部之前。
想法3.0就产生了,放弃局部的思想,将三个窗口间的关系利用总和来表示出了。首先将三个窗口分别设置为[0, k-1], [k, 2k-1], [2k, 3k-1],计算三个窗口分别的和,然后移动第一个窗口,如果移动后窗口的和大于原来的和,那么移动第一个窗口并且更新最大值。在假设第一个窗口基础上求第一个窗口和第二个窗口总和的最大值,这是非常关键的一步,如果仅仅求各自的最大值,就相当于人为割断了窗口间的联系,从而无法达到整体最大。如果第一和第二的总和大于之前的最大值,那么更新最大值,并且记录下这个时候窗口的位置。第三步同样也是在第一第二个窗口移动完的基础之上进行计算的,并且比较三个窗口的最大值与移动前最大值。如果大于移动前的最大值,那么记录移动后的窗口信息。
并且由于滑动窗口是三个窗口同步向前的,并没有停止的操作,所以保证了三个窗口不会发生重叠。
源码展示
class Solution {
public:
vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
vector<int> iRet;
int iSum[3] = { 0 }, iMax[3] = { 0 }, iIndex = 0, iIndex1 = 0, iIndex2 = k;
iRet.resize(3);
for(int i = 2 * k; i < nums.size(); i++)
{
iSum[0] += nums[i - 2 * k];
iSum[1] += nums[i - k];
iSum[2] += nums[i];
if(i >= 3 * k - 1)
{
if(iSum[0] > iMax[0])
{
iMax[0] = iSum[0];
iIndex = i - 3 * k + 1;
}
if(iSum[1] + iMax[0] > iMax[1])
{
iMax[1] = iSum[1] + iMax[0];
iIndex1 = iIndex;
iIndex2 = i - 2 * k + 1;
}
if(iSum[2] + iMax[1] > iMax[2])
{
iMax[2] = iMax[1] + iSum[2];
iRet = {iIndex1, iIndex2, i - k + 1};
}
iSum[0] -= nums[i - 3 * k + 1];
iSum[1] -= nums[i - 2 * k + 1];
iSum[2] -= nums[i - k + 1];
}
}
return iRet;
}
};
运行结果

LeetCode-689 三个无重叠子数组的最大和的更多相关文章
- Java实现 LeetCode 689 三个无重叠子数组的最大和(换方向筛选)
689. 三个无重叠子数组的最大和 给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为k,我们要使这3*k个项的和最大化. 返回每个区间起始索引的列表(索引从 0 ...
- [Swift]LeetCode689. 三个无重叠子数组的最大和 | Maximum Sum of 3 Non-Overlapping Subarrays
In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. E ...
- [LeetCode] Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和
In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. E ...
- [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 ...
- [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 ...
- [Swift]LeetCode1031. 两个非重叠子数组的最大和 | Maximum Sum of Two Non-Overlapping Subarrays
Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping ...
- 剑指offer三十之连续子数组的最大和
一.题目 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...
- [LeetCode] 918. Maximum Sum Circular Subarray 环形子数组的最大和
Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty ...
- 剑指Offer(三十):连续子数组的最大和
.# 剑指Offer(三十):连续子数组的最大和 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net ...
- leetcode面试题42. 连续子数组的最大和
总结一道leetcode上的高频题,反反复复遇到了好多次,特别适合作为一道动态规划入门题,本文将详细的从读题开始,介绍解题思路. 题目描述示例动态规划分析代码结果 题目 面试题42. 连续子数 ...
随机推荐
- 《HTTP权威指南》– 9.识别和认证
客户端识别与Cookie机制 承载用户相关信息的HTTP首部 From Email地址 User-Agent 浏览器软件 Referer 跳转链接<来自> Author ziation 用 ...
- <一>C++ STL
STL (standard template libaray - 标准模板库):是 C++ 标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架. 通俗来说:STL就 ...
- 二阶段目标检测网络-Mask RCNN 详解
ROI Pooling 和 ROI Align 的区别 Mask R-CNN 网络结构 骨干网络 FPN anchor 锚框生成规则 实验 参考资料 Mask RCNN 是作者 Kaiming He ...
- JavaScript:对象:如何判断对象是否有某个属性?操作符in
使用in运算符来判断,有返回true,没有返回false:
- C语言 根据掩码计算网段的起止ip
原文地址:https://www.yuque.com/docs/share/85a26263-484a-42f6-880b-2b511ae1bd20?# 根据ipv4掩码计算 #include < ...
- [WPF]数据绑定失效的问题
有可能的原因如下: 绑定的属性一定是属性而不能是字段,比如: public int data; 是无法生效的,而 public int data {get;set;} 这样才能生效
- 洛谷P1048 典型01背包问题
写在前面的话 蒟蒻在学习诸多图论算法之前,实际上没学过dp! 强说是学过也是只学了01背包,今天就来温习一下-- DP是啥? 动态规划(Dynamic Programming,DP)是运筹学的一个分支 ...
- python3.10调用邮件SMTP报错: ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)解决
一: python3.10调用邮件SMTP报错: ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake fa ...
- 你想成为.Net 7的技术高手吗?来这里看看
前言: 你是否时常觉得,整天搞些Curd和增删改查.这些毫无意义的东西,完全是浪费生命.想要进阶,成为高手.却苦于找不到方法,没有一套系统性的东西. 有鉴于此,新建了一个群,方便大家一起交流和分享一些 ...
- 前端知识点(js部分)
目录 一.JS简介 简介 ECMAScript的历史 二.JS基础 1.注释语法 2.引入js的多种方式 3.结束符号 三.变量与常量 编写和运行js代码的两种方式 变量声明 四.基本数据类型 1.数 ...