LeetCode689. Maximum Sum of 3 Non-Overlapping Subarrays
来源:互联网 发布:避风港原则淘宝 编辑:程序博客网 时间:2024/06/03 18:23
Solution1: Divide and Conquer
This question asks for the three non-overlapping intervals with maximum sum. So this can be divided into 3 parts – find 3 non-overlapping intervals respectively, and combining the results to get the 3 non-overlapping intervals we want. Since each interval is of length k, suppose the start index of the middle interval is i
, then the range of i
’s value is: k <=i <= n-2k
. Actually this i
has also indicated the limits of the range of the first interval and the range of the last interval. Hence we have the following DP components:
left[i] stores the start index for the first interval in range [0, i]right[i] stores the start index for the third interval in range [i, n - 1]
After that we can test every possible start index of middle interval, i.e. k <= i <= n - 2k
. And based on the above 2 DP results, we can easily get the first and third max sum intervals. The runtime of this process is O(n)
.
Note that this question asks for the lexicographical smallest order interval, that is, when there are two intervals with the same max sum, we always select the leftmost one. So in this solution, for the first interval, since we are iterating from left to right, the comparison if
statement use currSum > total
. And for the third interval, we are iterating from right to left, the comparison if
statement use currSum >= total
.
Another trick we use here, to ensure the algorithm runs in O(n)
time, is that we use predix sum to get the sum of a consecutive subarray in O(1)
time. Otherwise, if we calaulate the interval sum each time, that would be O(k)
time for each interval.
Run time complexity of this algorithm is O(n)
. Space complexity is O(n)
. n
is the length of the input nums
array.
class Solution { public int[] maxSumOfThreeSubarrays(int[] nums, int k) { int n = nums.length; int[] sum = new int[n + 1]; int[] left = new int[n]; int[] right = new int[n]; int[] ret = new int[3]; // First get the prefix sum of nums. // Prefix sum enables us to get the sum of k consecutive element in O(1) time for (int i = 0; i < n; i++) { sum[i + 1] = sum[i] + nums[i]; } // DP for the left intetval max sum for (int i = k, tot = sum[k] - sum[0]; i < n; i++) { if (sum[i + 1] - sum[i - k + 1] > tot) { tot = sum[i + 1] - sum[i - k + 1]; left[i] = i - k + 1; } else { left[i] = left[i - 1]; } } // DP for the right interval max sum right[n - k] = n - k; for (int i = n - 1 - k, tot = sum[n] - sum[n - k]; i >= 0; i--) { if (sum[i + k] - sum[i] >= tot) { tot = sum[i + k] - sum[i]; right[i] = i; } else { right[i] = right[i + 1]; } } // Find the max sum by iterating through the middle interval index based on above 2 cache. int maxSum = 0; for (int i = k; i <= n - 2 * k; i++) { int l = left[i - 1], r = right[i + k]; int tot = sum[l + k] - sum[l] + sum[r + k] - sum[r] + sum[i + k] - sum[i]; if (tot > maxSum) { ret[0] = l; ret[1] = i; ret[2] = r; maxSum = tot; } } return ret; }}
Solution2: Generalized method
This is a generalized method for 689. Maximum Sum of 3 Non-Overlapping Subarrays
.
In this solution, dp[i][j]
is used for recording for ith interval, what are the max sums for first j numbers in each position. And index[i][j]
is used for recording for ith interval, what are the current start index for first j numbers that made up the max sum.
Thus after the searching ends, dp[n][nums.length]
stores the max sum we can get and index[n][nums.length]
stores the start index of last interval for the max sum. And now we can search backwards for each previous start index based on the start index of current interval. Because the start index of previous interval is the index stored in index[i - 1][current start index]
, which is the max sum of the subarray before current start index.
Run time complexity is O(n * len)
where n
is the number of intervals needed and len is the length of input array.
Space complexity is O(n * len)
as well.
class MaxSumOfThreeSubarrays { /** * * @param nums input array of numbers * @param k length of each interval * @param n number of intervals * @return start index of each interval that has the maximum sum */ public int[] maxSumOfThreeSubarrays(int[] nums, int k, int n) { int[][] dp = new int[n + 1][nums.length + 1]; int[][] index = new int[n + 1][nums.length + 1]; int tot = 0; // prefix sum int[] sum = new int[nums.length + 1]; for (int i = 0; i < nums.length; i++) { sum[i + 1] = nums[i] + sum[i]; } for (int i = 1; i <= n; i++) { for (int j = k - 1; j < nums.length; j++) { int tmpMax = sum[j + 1] - sum[j - k + 1] + dp[i - 1][j - k + 1]; if (tmpMax > dp[i][j]) { dp[i][j + 1] = tmpMax; index[i][j + 1] = j - k + 1; } else { dp[i][j + 1] = dp[i][j]; index[i][j + 1] = index[i][j]; } } } int[] ret = new int[n]; int prev = nums.length; for (int i = n; i > 0; i--) { ret[i - 1] = index[i][prev]; prev = ret[i - 1]; } return ret; }}
- LeetCode689. Maximum Sum of 3 Non-Overlapping Subarrays
- Maximum Sum of 3 Non-Overlapping Subarrays
- 689. Maximum Sum of 3 Non-Overlapping Subarrays
- LWC 52:689. Maximum Sum of 3 Non-Overlapping Subarrays
- 689. Maximum Sum of 3 Non-Overlapping Subarrays
- [leetcode]Maximum Sum of 3 Non-Overlapping Subarrays
- [LeetCode] DP 之 Maximum sum of 3 Non-Overlapping Subarrays
- 689. Maximum Sum of 3 Non-Overlapping Subarrays
- 689. Maximum Sum of 3 Non-Overlapping Subarrays
- 算法练习(22):Maximum Sum of 3 Non-Overlapping Subarrays
- 689. Maximum Sum of 3 Non-Overlapping Subarrays 【Hard】 动态规划
- Fast Calibration of Embedded Non-overlapping Cameras
- Find longest covered length of non overlapping interval subsets
- LeetCode 53. Maximum Subarrays
- 最大重叠区间数目 Maximum number of overlapping intervals
- 435. Non-overlapping Intervals
- 435. Non-overlapping Intervals
- 435. Non-overlapping Intervals
- Codeforces 872 A Search for Pretty Integers
- 欢迎使用CSDN-markdown编辑器
- 十大基础实用算法及其拓展
- sql中通过from接一个查询结果
- Java 计算两个日期相差的天数
- LeetCode689. Maximum Sum of 3 Non-Overlapping Subarrays
- linux-命令
- 1.1 HTTP基本概念
- filter与interceptor的区别
- 笔记-有关于Vim
- android解决小米手机上选择照片路径为null问题
- 0,‘0’,‘\0’,null的区别
- SpringCloud使用Feign进行服务调用
- 自定义 Android Studio Locat 的输出颜色