我需要编写一个函数,将正整数,正整数B和正整数C的数组A作为输入。 然后,该函数应返回长度为B和C的A的两个不相交子数组的元素的总和,这些元素的和为最大。例如,如果A = [3、11、1、2、9、4、5、6、1],B = 4和C = 2,则该函数应返回38。这是因为两个最大的不相交子数组长度为B和C的A为[9,4,5,6]和[3,11]。第一个子数组的元素之和为9 + 4 + 5 + 6 = 24,第二个子数组的元素之和为3 + 11 = 14,所以两个子数组的总和为38。
我编写了一个遍历A的函数,找到长度为B的A的所有子数组和长度为C的A的所有子数组,然后找到最大B长度的子数组的元素之和和最大的C长子数组的元素。起初我以为我可以将最大的C长子阵列和最大的B长子阵列相加得出38。但是后来我意识到我的函数不能确保B长子阵列和C长子阵列是不相交,而是仅找到长度分别为B和C的A的最大子数组,这是不够的。
它在上面的示例中有效,但是请考虑以下示例: A = [3,7,10,5,2,1,3,4],B = 4,C =2。在这里,仅找到最大的B长子阵列和最大的C长子阵列将产生[3, 7,10,5]和[7,10]。然后,该函数将继续求和3 + 7 + 10 + 5 = 25和7 + 10 = 17并返回38。但这并不可行,因为这两个子数组不是不相交的子数组。该函数应该返回[3,7,10,5]和[3,4]作为最大的B长和C长不交集子数组。然后,它应该对元素求和并得到32。换句话说,当长度为A且长度为B和C的最大子数组重叠时,函数应找到这样的B长度子数组和C长度子数组的组合,从而最大程度地增加要素。到目前为止,这是我的代码:
function solution(A, B, C) {
var groupB = [];
var sumgroupB;
var maxSumArrayB;
var valuesSumsBArray = [];
if (A.length < (B + C)) {
return -1;
} else {
for (var i = 0; i < A.length; i++) {
if (i+B<=A.length) {
groupB = A.slice(i, i+B);
sumgroupB = groupB.reduce(function sum(a, b) { return a+b} );
valuesSumsBArray.push(sumgroupB);
}
}
maxSumArrayB = Math.max(...valuesSumsBArray);
}
var groupC = [];
var sumgroupC;
var maxSumArrayC;
var valuesSumsCArray = [];
if (A.length < (B + C)) {
return -1;
} else {
for (var i = 0; i < A.length; i++) {
if (i+C<=A.length) {
groupC = A.slice(i, i+C);
sumgroupC = groupC.reduce(function sum(a, b) { return a+b} );
valuesSumsCArray.push(sumgroupC);
}
}
maxSumArrayC = Math.max(...valuesSumsCArray);
}
return [maxSumArrayB, maxSumArrayC];
}
console.log(solution([3, 11, 1, 2, 9, 4, 5, 6, 1], 4, 2))
如何解决该问题,以确保该函数不会汇总A的最大B长度和C长度子数组的元素,而是汇总最大的DISJOINT B长度和C的元素长子数组(使最终总和最大化的两个子数组)?
答案 0 :(得分:0)
function solution(A, B, C) {
let max = -Infinity;
for(let startB = 0; startB < A.length - B; startB++) {
// C is before B
for(let startC = 0; startC + C < startB; startC++) {
const sum = [...A.slice(startC, startC + C), ...A.slice(startB, startB + B)].reduce((a, b) => a + b, 0);
if(sum > max) max = sum;
}
// C is behind B
for(let startC = startB + B; startC < A.length; startC++) {
const sum = [...A.slice(startC, startC + C), ...A.slice(startB, startB + B)].reduce((a, b) => a + b, 0);
if(sum > max) max = sum;
}
}
return max;
}
答案 1 :(得分:0)
您可以首先为每个子集的和获得一个数组,然后检查索引,并仅从不重叠的索引中获取和。
function getSums(array, size) {
var sum = array.slice(0, --size).reduce((a, b) => a + b, 0);
return array.slice(size).map((v, i) => sum += v - (array[i - 1] || 0));
}
function solution(array, ...sizes) {
var sums = sizes.map(l => getSums(array, l)),
i, j,
max = 0;
for (i = 0; i < sums[0].length; i++) {
for (j = 0; j < sums[1].length; j++) {
if (j >= i + sizes[0] || j + sizes[1] <= i) {
max = Math.max(max, sums[0][i] + sums[1][j]);
}
}
}
return max;
}
console.log(solution([3, 11, 1, 2, 9, 4, 5, 6, 1], 4, 2));
console.log(solution([3, 7, 10, 5, 2, 1, 3, 4], 4, 2));