• [LeetCode] 377. Combination Sum IV 组合之和 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?

    Credits:
    Special thanks to @pbrother for adding this problem and creating all test cases.

    解法1:递归。按照前面I, II的思路用递归来解,会TLE,比如:OJ一个test case为[4,1,2] 32,结果是39882198,用递归需要好几秒时间。

    解法2:动态规划DP来解。这道题类似于322. Coin Change ,建一个一维数组dp,dp[i]表示目标数target为i时解的个数,从1遍历到target,对于每一个数i,遍历nums数组,如果i>=x, dp[i] += dp[i - x]。比如[1,2,3] 4,当计算dp[3]时,3可以拆分为1+x,而x即为dp[2],3也可以拆分为2+x,x为dp[1],3同样可以拆为3+x,x为dp[0],把所有情况加起来就是组成3的所有解。

    Java: Recursive

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

    Java:

    private int[] dp;
    
    public int combinationSum4(int[] nums, int target) {
        dp = new int[target + 1];
        Arrays.fill(dp, -1);
        dp[0] = 1;
        return helper(nums, target);
    }
    
    private int helper(int[] nums, int target) {
        if (dp[target] != -1) {
            return dp[target];
        }
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            if (target >= nums[i]) {
                res += helper(nums, target - nums[i]);
            }
        }
        dp[target] = res;
        return res;
    }
    

    Java:  

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

    Java:

    class Solution {
        public int combinationSum4(int[] nums, int target) {
            if(nums==null || nums.length==0)
                return 0;
    
            int[] dp = new int[target+1];
    
            dp[0]=1;
    
            for(int i=0; i<=target; i++){
               for(int num: nums){
                   if(i+num<=target){
                       dp[i+num]+=dp[i];
                   }
               }
            }
    
            return dp[target];
        }
    } 

    Python:

    class Solution(object):
        def combinationSum4(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: int
            """
            dp = [0] * (target+1)
            dp[0] = 1
            nums.sort()
    
            for i in xrange(1, target+1):
                for j in xrange(len(nums)):
                    if nums[j] <= i:
                        dp[i] += dp[i - nums[j]]
                    else:
                        break
    
            return dp[target]  

    Python:

    class Solution(object):
        def combinationSum4(self, nums, target):
            nums, combs = sorted(nums), [1] + [0] * (target)
            for i in range(target + 1):
                for num in nums:
                    if num  > i: break
                    if num == i: combs[i] += 1
                    if num  < i: combs[i] += combs[i - num]
            return combs[target]  

    C++:

    class Solution {
    public:
        int combinationSum4(vector<int>& nums, int target) {
            vector<int> dp(target + 1, 0);
            dp[0] = 1;
            sort(nums.begin(), nums.end());
    
            for (int i = 1; i <= target; ++i) {
                for (int j = 0; j < nums.size() && nums[j] <= i; ++j) {
                    dp[i] += dp[i - nums[j]];
                }
            }
    
            return dp[target];
        }
    };  

    类似题目:

    [LeetCode] 322. Coin Change 硬币找零

    [LeetCode] 39. Combination Sum 组合之和

    [LeetCode] 40. Combination Sum II 组合之和 II

    [LeetCode] 216. Combination Sum III 组合之和 III

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    找出互联网符合的产品实例
    以软件周期来说明不同的测试的使用情况
    scrapy多个page爬取, post请求, 通过爬到的URL继续发请求爬页面
    Scrapy 安装, 基础使用, 持久化存储
    Linux nginx+uWSGI+django+virtualenv+supervisor发布web服务器
    Linux Nginx
    Linux virtualenv, virtualenvwrapper, pip freeze
    Linux Python安装
    Redis, Python操作Redis, Linux操作Redis, Redis命令, Redis发布订阅, Redis持久化, Redis主从同步
    爬虫 selenium
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8674184.html
Copyright © 2020-2023  润新知