# Best Sum

Updated: 01 February 2024

# Problem

Essentially the same as the How Sum question but our goal here is to find the shortest array that yields the sum we are interested in. If there are multiple equally short options then we can take any one

# Base Implementation

The solution to this is almost identical to the How Sum questio but we don’t early return when we find a solution of a subtree but instead we store the result of the best subtree as we iterate through

`dynamic-programming/memoization/best-sum.ts`

```
export const bestSum = (target: number, nums: number[]): number[] | null => {
if (target == 0) return [];
if (target < 0) return null;
let shortest: number[] | null = null;
for (let num of nums) {
const remainder = target - num;
const remainderCombination = bestSum(remainder, nums);
if (remainderCombination) {
const combination = [...remainderCombination, num];
if (shortest == null || shortest.length > combination.length)
shortest = combination;
}
}
return shortest;
};
```

In the above solution with $m=target$ and $n=length of nums$ the time complexity is $O(n^m * m)$ and the space complexity is $O(m^2)$

# With memoization

We can implement memoizatio based on the target:

`dynamic-programming/memoization/best-sum-memo.ts`

```
type Memo = Record<number, number[] | null>;
export const bestSum = (
target: number,
nums: number[],
memo: Memo = {}
): number[] | null => {
if (target in memo) return memo[target]
if (target == 0) return [];
if (target < 0) return null;
let shortest: number[] | null = null;
for (let num of nums) {
const remainder = target - num;
const remainderCombination = bestSum(remainder, nums, memo);
if (remainderCombination) {
const combination = [...remainderCombination, num];
if (shortest == null || shortest.length > combination.length)
shortest = combination;
}
}
memo[target] = shortest;
return shortest;
};
```

The time complexity of this should now be $O(m^2 * n)$ and the space complexity of $O(m^2)$