1

I need to write a function that takes in as input an array A of positive integers, a positive integer B and a positive integer C. The function should then return the total sum of the elements of two disjoint subarrays of A of length B and C that maximize such sum. For example, if A = [3, 11, 1, 2, 9, 4, 5, 6, 1], B = 4 and C = 2, then the function should return 38. This is because the two largest disjoint subarrays of A of length B and C are [9, 4, 5, 6] and [3, 11]. The sum of the first subarray's elements is 9+4+5+6=24 and the sum of the second subarray's elements is 3+11=14, so the total sum of the two subarrays is 38.

I wrote a function that loops through A and finds all the subarrays of A of length B and all the subarrays of A of length C, and then finds the sum of the elements of the largest B-long subarray and the sum of the elements of the largest C-long subarray. At first I thought I could just sum up the largest C-long subarray and the largest B-long subarray to find 38. But then I realized that my function does not make sure that the B-long subarray and the C-long subarray be disjoint, but instead merely finds the largest subarrays of A of length B and C respectively, which is not enough.

It works in the above example, but consider the following example: A = [3, 7, 10, 5, 2, 1, 3, 4], B = 4, C = 2. Here, merely finding the largest B-long subarray and the largest C-long subarray would yield [3, 7, 10, 5] and [7, 10]. The function would then go on to sum 3+7+10+5=25 and 7+10=17 and return 38. But this is not okay, because those two subarrays are not disjoint subarrays. The function should instead return [3, 7, 10, 5] and and [3,4] as the largest B-long and C-long disjoint subarrays. It should then sum up the elements and get 32. In other words, when the largest subarrays of A of length B and C overlap, the function should find the combination of such B-long and C-long subarrays that maximizes the final sum of the elements. This is my code so far:

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)) 

How can I fix it to make sure that the function doesn't sum up the elements of the largest B-long and C-long subarrays of A, but instead sums up the elements of the largest DISJOINT B-long and C-long subarrays (the two ones that maximize the final sum)?

tommsyeah
  • 121
  • 3
  • 10

2 Answers2

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;
  }
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

you could get first an array for each subset sums and then check the indices and take only the sums form the indices which do not overlap.

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));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392