组合总和 Ⅳ

114 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

一、题目

LeetCode 组合总和 Ⅳ

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

示例 1:

输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。

示例 2:

输入:nums = [9], target = 3
输出:0

提示:

1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums 中的所有元素 互不相同
1 <= target <= 1000

二、题解

要从给定的数组中选取数组元素使得元素之和为目标整数target,需要计算这些元素组合的个数,数组中的元素可以无限次使用(重复也可以),元素组合顺序不同也视为不同的组合。

方法一

对此可以使用动态规划来计算,首先定义dp数组,然后dp[i]就表示元素组合之和为i的组合数。初始的当i = 0的时候,所以数组大小就为目标整数target,初始的不选取任何元素时的元素之和就为0,只有一种组合,所以dp[0] = 1。然后遍历计算0 < i <= target的目标数,对于当前目标数i,要计算dp[i],可以将i之前的一个组合加上一个数组中的元素来得到,例如i为4的时候,可以用dp[1]组合加上元素4、dp[2]组合加上元素2、dp[3]组合加上元素1等等,当然选取的元素必须是原数组中的元素num,所以需要内循环遍历数组元素,最后需要累加dp[i - num],当然元素num得小于i才行,这样把num当成排列的最后一位来。最后需要返回dp[target]就可以了。对于顺序要求,外循环是遍历目标整数target,内循环就是遍历数组元素num,例如计算dp[4]时,如果数组元素含有1、3时,1为最后一个元素时加上dp[3],3为最后一个元素时会加上dp[1],这样就没问题了。

三、代码

方法一 Java代码

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

时间复杂度:O(n^2),需要遍历dp数组计算每一个目标值,同时遍历数组元素选取计算。

空间复杂度:O(n),动态规划需要使用一个数组。