Combination Sum IV

https://leetcode.com/problems/combination-sum-iv/#/description

DFS Solution(Time Limit Exceeded)

public class Solution {
    int res;
    public int combinationSum4(int[] nums, int target) {
        res = 0;
        Arrays.sort(nums);
        dfs(nums, target, 0, 0);

        return res;
    }

    private void dfs(int[] nums, int target, int sum, int start){
        if(target == sum){
            res++;
            return;
        }

        for(int i = 0; i < nums.length; i++){
            if(sum + nums[i] > target){
                break;
            }

            dfs(nums, target, sum + nums[i], 0);
        }
    }
}

Recursion(Time Limit Exceeded)

public class Solution {
    public int combinationSum4(int[] nums, int target) {
        if (target == 0) {
            return 1;
        }
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            if (target >= nums[i]) {
                res += combinationSum4(nums, target - nums[i]);
            }
        }
        return res;
    }
}

DP(bottom-up solution)

//    dp[i] denotes 'valid combinations number for i' until now(when at some position of nums)
//    if nums[j] > i break, 
//    if nums[j] == i, dp[i]++, 
//    if nums[j] < i, dp[i] += dp[i - nums[j]].
//    return dp[target]

public class Solution {
    public int combinationSum4(int[] nums, int target) {
        int[] dp = new int[target + 1];
        // dp[i] denotes 
        Arrays.sort(nums);
        for(int i = 1; i <= target; i++){
            for(int j = 0; j < nums.length; j++){
                if(nums[j] > i){
                    break;
                }

                if(nums[j] == i){
                    dp[i]++;
                    break;
                }

                dp[i] += dp[i - nums[j]];
            }
        }

        return dp[target];
    }
}

DP(top-down solution)

public class Solution {
    private int[] dp;
    public int combinationSum4(int[] nums, int target) {
        dp = new int[target + 1];
        Arrays.fill(dp, -1);
        dp[0] = 1;
        Arrays.sort(nums);
        return helper(nums, target);
    }

    private int helper(int[] nums, int target){
        if(dp[target] != -1){
            return dp[target];
        }

        dp[target] = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] <= target){
                dp[target] += helper(nums, target - nums[i]);    
            }
        }

        return dp[target];
    }
}

Use HashMap as memorization

public class Solution {
    public int combinationSum4(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        if (nums == null || nums.length ==0 || target < 0 ) return 0;
        map.put(0, 1);
        return helper(nums, target, map);
    }

    private int helper(int[] nums, int target, Map<Integer, Integer> map){
        if(target < 0){
            return 0;
        }
        if (map.containsKey(target)) return map.get(target);
        int count = 0;

        for (int num: nums){
            count += helper(nums, target-num, map);
        }
        map.put(target, count);
        return count;
    }
}

Follow-up(what if we allow negative number):https://discuss.leetcode.com/topic/52290/java-follow-up-using-recursion-and-memorization

results matching ""

    No results matching ""