LeetCode/377. 组合总和 Ⅳ

377. 组合总和 Ⅳ

给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

示例 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nums = [1, 2, 3]
target = 4

所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

请注意,顺序不同的序列被视作不同的组合。

因此输出为 7。

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

本题虽然也叫做组合总和问题,但是和前面的问题不太一样,前面的组合总和问题都需要把所有的结果列出来,返回列表,而本题只需要返回所有结果的可能性。如果你试图将所有结果遍历出来然后返回result链表的大小,那么就会超时。因此我们根据官方的提示,尝试用动态规划的方法解决问题。至于这个题目怎么一下子想到动态规划,说实话这个可能就是做得多了才会有感觉吧,反正我一开始是没有想到的。

要用动态规划,我们能想到dp数组肯定是存放可能性的,然后就是需要找出状态转移方程,通过将几种情况列出来后我们发现,dp[i] = dp[i - nums[j]] +dp[i - nums[j + 1]]....这里[]里面的数都要大于零,状态转移方程找到后,问题迎刃而解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
假设nums[]为[1, 2, 3],我们通过列举几个例子来看下情况
target = 0时
dp([1, 2, 3], 0) = {}

target = 1时
dp([1, 2, 3], 1) = {1}
= U({1} x dp([1, 2, 3], 1 - 1))

target = 2时
dp([1, 2, 3], 2)
= U({1} x dp([1, 2, 3], 2 - 1), {1, 1}
{2} x dp([1, 2, 3], 2 - 2)) {2}

target = 3时
dp([1, 2, 3], 3)
= U({1} x dp([1, 2, 3], 3 - 1), {1, 1, 1} {1, 2}
{2} x dp([1, 2, 3], 3 - 2), {2, 1}
{3} x dp([1, 2, 3], 3 - 3)) {3}

target = 4时
dp([1, 2, 3], 4)
= U({1} x dp([1, 2, 3], 4 - 1), {1, 1, 1, 1} {1, 1, 2} {1 ,2, 1} {1, 3}
{2} x dp([1, 2, 3], 4 - 2), {2, 1, 1} {2, 2}
{3} x dp([1, 2, 3], 4 - 3)) {3, 1}

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 j = 0; j < nums.length; j++) {
if (nums[j] <= i) {
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
}

Comments