Combination Sum IV

题目
Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.

Example:

nums = [1, 2, 3]
target = 4

The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.

Therefore the output is 7.
Follow up:
What if negative numbers are allowed in the given array?
How does it change the problem?
What limitation we need to add to the question to allow negative numbers?

答案

class Solution {
    int[] dp = null;
    public int combinationSum4(int[] nums, int target) {
        if(target == 0) return 1;
        
        int ans = 0;
        dp = new int[target + 1];
        Arrays.fill(dp, -1);
        dp[0] = 1;
        recur(nums, target);
        return dp[target];
    }
    
    public int recur(int[] nums, int target) {
        // if(target == 0) return 1; This line is not needed if you have initilized dp[0] = 1
        if(dp[target] != -1) return dp[target];
        
        int ans = 0;
        for(int i = 0; i < nums.length; i++) {
            if(target >= nums[i]) {
                ans += recur(nums, target - nums[i]);                
            }
        }
        
        dp[target] = ans;
        return ans;
    }
}

Negative numbers can't be allowed in current question, because it would produce infinite number of combinations, because the length of a combination could be infinite

For example, with [-1,1], target = 1, you can have infinite many combinations that sum to target = 1

So, we really need to limit the problem to only find number of combinations of length < maxlen that sum to some target.

Use dp[i] to keep track of the map(length -> number of combinations)

class Solution {
    
    Map<Integer, Map<Integer, Integer>> dp_map = new HashMap<Integer, Map<Integer, Integer>>();

    public int combinationSum4(int[] nums, int target, int maxlen) {
        if(num == null || nums.length == 0 || maxlen <= 0) return 0;
        return recur(nums, 0, target, maxlen);
    }
    
    public int recur(int[] nums, int len, int target, int maxlen) {
        // Base cases
        if(len > maxlen) return 0;
        
        // Memorized values
        if(map.get(target) != null && map.get(target).containKeys(len))
            map.get(target).get(key);
        
        // Recursive cases
        
        int ans = 0;
        // If target is 0, there is at least 1 combination, namely the empty set {}
        if(target == 0) ans++;
        
        for(int i = 0; i < nums.length; i++) {
            ans += recur(nums, len + 1, target - nums[i], maxlen);
        }
        
        Map<Integer, Integer> len2combos = dp_map.get(target);
        if(len2combos == null) {
            len2combos = new HashMap<Integer, Integer>();
            dp_map.put(target, len2combos);
        }
        len2combos.put(len, ans);
        return ans;
    }
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容