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