import java.util.TreeMap;

class Solution {
  private TreeMap<Integer, Integer> cache;

  private int combinationSumRec(int[] nums, int target) {
    if (target < 0) {
      // Base: Target is below zero
      return 0;
    }

    if (target == 0) {
      // Base: We have found a possible combination
      return 1;
    }

    if (cache.containsKey(target)) {
      // Base: Target is already precomputed
      return cache.get(target);
    }

    int combinations = 0;
    for (int num : nums) {
      combinations += combinationSumRec(nums, target - num);
    }

    cache.put(target, combinations);
    return combinations;
  }

  public int combinationSum4(int[] nums, int target) {
    cache = new TreeMap<>();
    return combinationSumRec(nums, target);
  }
}