首页 > 代码库 > 377. Combination Sum IV
377. 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?
暴力法转化为动归---top down---memory search: 明白存储的是谁, 记忆化存储也可以用map, 本来觉得可以用dfs, 但是是求个数, 所以想到用
动归, 然后想到记忆化存储, 画图: 明白存的是target的个数, 后序遍历, dp[i] 就是从下面上来的个数.
动归: dp[i] = Uj=0 && i > nums[j] n sum(dp[i - dp[i - nums[j]]), 此处i不是遍历到第i个, 而是每次都应该遍历一遍
找到所有的状态 DP 解法: the key to solve DP problem is to think about how to create overlap,
how to re-solve subproblems(怎么制造复用)
暴力法 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; } 暴力法转化为动归---top down---memory search: 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; } 动归----bottom up 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]; }
错误的做法: 因为dp[j][i] != dp[j -1] + dp[j], 因为nums[j -1] 可能用多次, 不是只用一次, 这样就少写了情况, 看来不是维度越多越好, 只要找到一维, 按着这一个状态来递推就行, 一般是文中的题意变量作为状态, 不要老是想着遍历到第几个变量作为状态
for (int i = 1; i <= target; i++) { for (int j = 1; j <= nums.length; j++) { dp[j][i] = dp[j - 1][i]; if (i >= nums[j - 1]) dp[j][i] += dp[j - 1][i - nums[j - 1]]; } }
Follow up:
I think if there are negative numbers in the array, we must add a requirement that each number is only used one time, or either positive number or negative number should be used only one time, otherwise there would be infinite possible combinations.
For example, we are given:
{1, -1}, target = 1,
it‘s obvious to see as long as we choose n 1s and (n-1) -1s, it always sums up to 1, n can be any value >= 1.
377. Combination Sum IV
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。