689. Maximum Sum of 3 Non-Overlapping Subarrays三个不重合数组的求和最大值
[抄题]:
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.
[暴力解法]:
时间分析:
空间分析:
[优化后]:
时间分析:
空间分析:
[奇葩输出条件]:
[奇葩corner case]:
note中已经提示了length,就只需要考虑k k&length的关系就了
把“前i项”初始化为“第i项”,方便直接做差
for (int i = 1; i <= n; i++) { sums[i] = sums[i - 1] + nums[i - 1]; }
[思维问题]:
不知道为什么要用DP:每次都保存之前一组的状态,然后一个个向前更新和比价。
求一组固定为k长度的数组时可用。
//总和=本组和+之前组的和=本组最后之和-本组第一之和+之前的(从j - k开始的)dp求和值 int curSum = sums[j] - sums[j - k] + dp[i - 1][j - k];
[英文数据结构或算法,为什么不用别的数据结构或算法]:
dp数组里存储了结果,可以通过不断输入index来把结果取出来:
int index = n; for (int i = 2; i >= 0; i--) { res[i] = pos[i + 1][index]; System.out.println("index = " +index); System.out.println("res[i] = pos[i + 1][index] = " +res[i]); index = res[i]; System.out.println("index = " +index); System.out.println("----------------"); }
[一句话思路]:
按照第123组来操作,
总和=本组和+之前所有组的和
[输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):
[画图]:
[一刷]:
- 序列型dp所有的有关数组、有关二维数组都要增加1个单位,调用的时候也要+1,因为第一位拿来初始化了。不初始化就是默认为0
[二刷]:
- 发现把第0位给去掉了 不知道为何:
[1,2,1,2,6,7,5,1] 2 i = 1 i - 1 = 0 nums[i - 1] = 1 sum[i - 1] = 0 sum[i - 1] = 1 --------------- i = 2 i - 1 = 1 nums[i - 1] = 2 sum[i - 1] = 0 sum[i - 1] = 2 --------------- i = 3 i - 1 = 2 nums[i - 1] = 1 sum[i - 1] = 0 sum[i - 1] = 1 --------------- i = 4 i - 1 = 3 nums[i - 1] = 2 sum[i - 1] = 0 sum[i - 1] = 2 --------------- i = 5 i - 1 = 4 nums[i - 1] = 6 sum[i - 1] = 0 sum[i - 1] = 6 --------------- i = 6 i - 1 = 5 nums[i - 1] = 7 sum[i - 1] = 0 sum[i - 1] = 7 --------------- i = 7 i - 1 = 6 nums[i - 1] = 5 sum[i - 1] = 0 sum[i - 1] = 5 --------------- i = 8 i - 1 = 7 nums[i - 1] = 1 sum[i - 1] = 0 sum[i - 1] = 1 ---------------
[三刷]:
[四刷]:
[五刷]:
[五分钟肉眼debug的结果]:
[总结]:
dp是存储一组状态的,可以拿来调用
[复杂度]:Time complexity: O(n) Space complexity: O(n)
[算法思想:迭代/递归/分治/贪心]:
[关键模板化代码]:
[其他解法]:
[Follow Up]:
[LC给出的题目变变变]:
[代码风格] :
[是否头一次写此类driver funcion的代码] :
class Solution { public int[] maxSumOfThreeSubarrays(int[] nums, int k) { //ini: res[3], pos[4][n + 1], dp[4][n + 1] int n = nums.length; int[] res = new int[3]; int[] sum = new int[n + 1]; int[][] pos = new int[4][n + 1]; int[][] dp = new int[4][n + 1]; //cc if (nums == null || nums.length < 3 * k) return res; //ini:sum for (int i = 1; i <= n; i++) { int j = i - 1; System.out.println("i = "+i); System.out.println("i - 1 = "+j); System.out.println("nums[i - 1] = "+nums[i - 1]); System.out.println("sum[i - 1] = "+sum[i - 1]); sum[i - 1] = sum[i - 1] + nums[i - 1]; System.out.println("sum[i - 1] = "+sum[i - 1]); System.out.println("---------------"); } for (int i = 1; i <= 3; i++) { for (int j = k * i; j <= n; j++) { int curSum = sum[j] - sum[j - k] + dp[i - 1][j - k]; if (curSum > dp[i][j - 1]) { dp[i][j] = curSum; pos[i][j] = j - k; }else { dp[i][j] = dp[i][j - 1]; pos[i][j] = pos[i][j - 1]; } } } //retrieve the answer int index = n; for (int i = 2; i >= 0; i--) { // res[i] = pos[i + 1][index]; index = res[i]; } //return return res; } }