描述
Alice 和 Bob 在一个漂亮的果园里面工作,果园里面有N棵苹果树排成了一排,这些苹果树被标记成1 - N号。
Alice 计划收集连续的K棵苹果树上面的所有苹果,Bob计划收集连续的L棵苹果树上面的所有苹果。
Alice和Bob选择的区间不可以重合,你需要返回他们能够最大收集的苹果数量。
- N 是整数且在以下范围内:[2,600]
- K 和 L 都是整数且在以下范围内:[1,N-1]
- 数组A的每个元素都是以下范围内的整数:[1,500]
在线评测地址
LintCode 领扣样例1
示例 1:
输入:
A = [6, 1, 4, 6, 3, 2, 7, 4]
K = 3
L = 2
输出: 24
解释:因为Alice 可以选择3-5颗树然后摘到4 + 6 + 3 = 13 个苹果, Bob可以选择7-8棵树然后摘到7 + 4 = 11个苹果,因此他们可以收集到13 + 11 = 24。
样例2
示例 2:
输入:
A = [10, 19, 15]
K = 2
L = 2
输出: -1
解释:因为对于 Alice 和 Bob 不能选择两个互不重合的区间。
解题思路
这题的重点在于如何快速地得到数组上一个区间内所有值的和,我们可以用前缀和来解决。
prefixSum(i)代表数组的前i个数的和,我们可以通过一次遍历求出,prefixSum(i) = prefixSum(i - 1) + A(i)。
那么rangeSum(l, r) = prefixSum(r) - prefixSum(l - 1),就可以在O(1)时间内求出数组上的区间和。
代码思路
- 计算A数组的前缀和数组prefixSum。
- 计算前缀中长度为K的子段和最大值,用prefixK记录。
- 计算前缀中长度为L的子段和最大值,用prefixL记录。
- 计算后缀中长度为K的子段和最大值,用postfixK记录。
- 计算后缀中长度为L的子段和最大值,用postfixL记录。
- 由于选择的两个区间不可重复,所以枚举分界点,分为两种情况:
- 取prefixK[i] + postfixL[i + 1]。
- 取prefixL[i] + postfixK[i + 1]。
复杂度分析
设苹果树个数为N。
时间复杂度
- 在线性时间内计算前缀和,前后缀最大值和结果,总时间复杂度为O(N)。
空间复杂度
- 一共需要5个额外的长为N的数组,空间复杂度为O(N)。
public class Solution {
/**
* @param A: a list of integer
* @param K: a integer
* @param L: a integer
* @return: return the maximum number of apples that they can collect.
*/
public int PickApples(int[] A, int K, int L) {
int n = A.length;
if (n < K + L) {
return - 1;
}
int[]</