All files / algorithms/dynamic-programming/sum how-sum.ts

100% Statements 15/15
90.9% Branches 10/11
100% Functions 2/2
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 4634x                                                 1x         25x 22x 18x   11x 18x 18x 6x 6x       5x 5x    
/**
 * Return an array containing any combination of the elements taken from the array of numbers
 * to add up to the target sum.
 *
 * The elements from the array of numbers can be used more than once.
 *
 * If no combination exists that adds up to the target sum, null is returned.
 *
 * The brute-force implementation has the following complexity:
 * - Time complexity: O(m * n^m)
 * - Space complexity: O(m)
 *
 * The memoised version has the following complexity:
 * - Time complexity: O(n * m^2)
 * - Space complexity: O(m^2)
 *
 * Where
 * - "n" is the size of the array of numbers (branching factor)
 * - "m" is the target sum (height of the tree)
 *
 * @param targetSum the number to construct summing the numbers from the arrays
 * @param numbers the array of numbers
 * @param buffer the object used for memoisation
 * @returns an array of numbers that add up to the target sum
 */
export default function howSum(
  targetSum: number,
  numbers: number[],
  buffer: Record<number, number[] | null> = {},
): number[] | null {
  if (targetSum in buffer) return buffer[targetSum];
  if (targetSum === 0) return [];
  if (targetSum < 0) return null;
 
  for (const number of numbers) {
    const result = howSum(targetSum - number, numbers, buffer);
    if (result !== null) {
      buffer[targetSum] = [...result, number];
      return buffer[targetSum];
    }
  }
 
  buffer[targetSum] = null;
  return buffer[targetSum];
}