4

I found the following problem when preparing for an interview:

3 can be written as 1+1+1, 1+2, 2+1; 4 can be written as 1+1+1+1, 1+1+2, 2+2, 1+2+1, 2+1+1, 3+1, 1+3; Given an integer, how many possible expressions exist? (1+2 and 2+1 are different)

So this is fairly straightforward to write a brute force algorithm to calculate that and get the set all the sets of numbers that do it:

private static Set<List<Integer>> getIntegersSum(int num) {
  Set<List<Integer>> returnSet = new HashSet<List<Integer>>();

  if (num == 0) {
   returnSet.add(new LinkedList<Integer>());
   return returnSet;
  }

  for (int i = 1; i <= num; i++) {
    Set<List<Integer>> listNMinI = getIntegersSum(num - i);
    for (List<Integer> l : listNMinI) {
      l.add(0, i);
      returnSet.add(l);
    }
  }

  return returnSet;
}

Now I believe the recurrence relation that describes the complexity of this algorithm is:

T(0) = \Theta (1)
T(n) = O(n) + \Sum_{i=0}^{n-1} T(i)

I'm not quite sure how to arrive at big-oh complexity from this recurrence relation. I would also like to know if there is a closed form solution for the question (how many combinations like that we will have for each number).

I'm also not sure what the complexity would be if we memoize this algorithm by caching the results of each call (similarly to how you can speed up fibonacci).

1 Answers1

2

There are 2n - 1 - 1 of such expressions.

There are a number of ways to approach this problem.

I use result of this problem:

There are n candies. How many ways are there to split all n candies to k people (0 candy can be given)?

The order is important, since the portions go to different people. The solution is (n + k - 1)C(k - 1). We add k - 1 separators into the mix (which makes the sum n + k - 1), and we try to find the number of ways to insert the separators to separate the candies into k parts. Think of n + k - 1 boxes in a line to place the candies and separators, and we want to find number of ways to choose k - 1 slots for the separators, which separates the boxes into k portions.


Back to this problem, we need to answer this sub-problem:

How many ways to express n as sum of k positive numbers?

We can reuse the result from the candy splitting problem above, but we need to reserve k to prevent the terms to be 0. So the result will be ((n - k) + k - 1)C(k - 1), which simplifies to (n - 1)C(k - 1). (The (n - k) is due to we putting away k for each of the k terms).

So the final result will be Sum [i = 2..n] (n - 1)C(i - 1), since the expression contains at least 2 terms, and at most n terms. We know that Sum [i = 1..n] (n - 1)C(i - 1) = 2n - 1, so Sum [i = 2..n] (n - 1)C(i - 1) = 2n - 1 - 1.

Another way to approach this problem is explained by @MarkDickinson in the comment. The reasoning is more straight-forward.

Between each pair of candies, either there's a separator or there isn't. That immediately gives 2^(n-1) possibilities. For whatever reason the OP is excluding the single case where we've got only 1 portion, so subtract 1 to get 2^(n-1) - 1.

to make the argument more solid. Since the problem only allow positive terms, we can only insert 1 separator between the candies, and we can only insert them between the candies, not the 2 ends. Therefore, there are (n - 1) places that the separator can appear.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
  • 1
    Simpler: between each pair of candies, either there's a separator or there isn't. That immediately gives `2^(n-1)` possibilities. For whatever reason the OP is excluding the single case where we've got only 1 portion, so subtract `1` to get `2^(n-1) - 1`. – Mark Dickinson Dec 22 '12 at 17:38
  • @MarkDickinson: That's a better approach to the problem. – nhahtdh Dec 22 '12 at 17:41