|
1 | 1 | package com.fishercoder.solutions; |
2 | 2 |
|
3 | | -import com.fishercoder.common.utils.CommonUtils; |
4 | | - |
5 | 3 | import java.util.ArrayList; |
6 | 4 | import java.util.Arrays; |
7 | 5 | import java.util.List; |
8 | | -/**Given an integer array with all positive numbers and no duplicates, |
| 6 | + |
| 7 | +/** |
| 8 | + * 377. Combination Sum IV |
| 9 | + * Given an integer array with all positive numbers and no duplicates, |
9 | 10 | * find the number of possible combinations that add up to a positive integer target. |
10 | 11 |
|
11 | 12 | Example: |
|
29 | 30 | Follow up: |
30 | 31 | What if negative numbers are allowed in the given array? |
31 | 32 | How does it change the problem? |
32 | | - What limitation we need to add to the question to allow negative numbers?*/ |
| 33 | + What limitation we need to add to the question to allow negative numbers? |
| 34 | + */ |
| 35 | + |
33 | 36 | public class _377 { |
34 | | - /**since this question doesn't require to return all the combination result, instead, it just wants one number, we could use DP |
35 | | - the idea is similar to Climbing Stairs. |
36 | | - adopted this solution: https://discuss.leetcode.com/topic/52186/my-3ms-java-dp-solution*/ |
37 | | - public int combinationSum4(int[] nums, int target) { |
38 | | - Arrays.sort(nums); |
39 | | - int[] result = new int[target + 1]; |
40 | | - for (int i = 1; i < result.length; i++) { |
41 | | - for (int n : nums) { |
42 | | - if (n > target) { |
43 | | - break; |
44 | | - } else if (n == target) { |
45 | | - result[i]++; |
46 | | - } else { |
47 | | - result[i] += result[i - n]; |
| 37 | + |
| 38 | + public static class Solution1 { |
| 39 | + /** |
| 40 | + * this normal backtracking recursive solution will end up in MLE by this testcase: [4,2,1], 32 |
| 41 | + */ |
| 42 | + public int combinationSum4(int[] nums, int target) { |
| 43 | + List<List<Integer>> result = new ArrayList(); |
| 44 | + Arrays.sort(nums); |
| 45 | + backtracking(nums, target, new ArrayList(), result); |
| 46 | + return result.size(); |
| 47 | + } |
| 48 | + |
| 49 | + private void backtracking(int[] nums, int target, List<Integer> list, |
| 50 | + List<List<Integer>> result) { |
| 51 | + if (target == 0) { |
| 52 | + result.add(new ArrayList(list)); |
| 53 | + } else if (target > 0) { |
| 54 | + for (int i = 0; i < nums.length; i++) { |
| 55 | + list.add(nums[i]); |
| 56 | + backtracking(nums, target - nums[i], list, result); |
| 57 | + list.remove(list.size() - 1); |
48 | 58 | } |
49 | 59 | } |
50 | 60 | } |
51 | | - return result[target]; |
52 | 61 | } |
53 | 62 |
|
54 | | - //this normal backtracking recursive solution will end up in TLE. |
55 | | - public List<List<Integer>> combinationSum4_printout(int[] nums, int target) { |
56 | | - List<List<Integer>> result = new ArrayList(); |
57 | | - Arrays.sort(nums); |
58 | | - backtracking(0, nums, target, new ArrayList(), result); |
59 | | - return result; |
60 | | - } |
| 63 | + public static class Solution2 { |
| 64 | + /** |
| 65 | + * Since we don't need to get all of the combinations, instead, |
| 66 | + * we only need to get the possible count, I can use only a count instead of "List<List<Integer>> result" |
| 67 | + * However, it also ended up in TLE by this testcase: [1,2,3], 32 |
| 68 | + */ |
| 69 | + public static int count = 0; |
| 70 | + public int combinationSum4(int[] nums, int target) { |
| 71 | + Arrays.sort(nums); |
| 72 | + backtracking(nums, target, new ArrayList()); |
| 73 | + return count; |
| 74 | + } |
61 | 75 |
|
62 | | - private void backtracking(int start, int[] nums, int target, ArrayList temp, |
63 | | - List<List<Integer>> result) { |
64 | | - if (target == 0) { |
65 | | - List<Integer> newTemp = new ArrayList(temp); |
66 | | - result.add(newTemp); |
67 | | - } else if (target > 0) { |
68 | | - for (int i = start; i < nums.length; i++) { |
69 | | - temp.add(nums[i]); |
70 | | - backtracking(i, nums, target - nums[i], temp, result); |
71 | | - temp.remove(temp.size() - 1); |
| 76 | + private void backtracking(int[] nums, int target, List<Integer> list) { |
| 77 | + if (target == 0) { |
| 78 | + count++; |
| 79 | + } else if (target > 0) { |
| 80 | + for (int i = 0; i < nums.length; i++) { |
| 81 | + list.add(nums[i]); |
| 82 | + backtracking(nums, target - nums[i], list); |
| 83 | + list.remove(list.size() - 1); |
| 84 | + } |
72 | 85 | } |
73 | 86 | } |
74 | 87 | } |
75 | 88 |
|
76 | | - public static void main(String... strings) { |
77 | | - _377 test = new _377(); |
78 | | - int[] nums = new int[]{1, 2, 3}; |
79 | | - int target = 4; |
80 | | - CommonUtils.printListList(test.combinationSum4_printout(nums, target)); |
| 89 | + public static class Solution3 { |
| 90 | + /** |
| 91 | + * Since this question doesn't require to return all the combination result, instead, it just wants one number, we could use DP |
| 92 | + * the idea is similar to Climbing Stairs. |
| 93 | + * |
| 94 | + * The idea is very clear as the code speaks for itself: |
| 95 | + * It's easy to find the routine |
| 96 | + * dp[0] = 0; |
| 97 | + * dp[1] = 1; |
| 98 | + * ... |
| 99 | + * |
| 100 | + * Reference: https://discuss.leetcode.com/topic/52186/my-3ms-java-dp-solution |
| 101 | + */ |
| 102 | + public int combinationSum4(int[] nums, int target) { |
| 103 | + Arrays.sort(nums); |
| 104 | + int[] result = new int[target + 1]; |
| 105 | + for (int i = 1; i < result.length; i++) { |
| 106 | + for (int num : nums) { |
| 107 | + if (num > i) { |
| 108 | + break; |
| 109 | + } else if (num == i) { |
| 110 | + result[i]++; |
| 111 | + } else { |
| 112 | + result[i] += result[i - num]; |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | + return result[target]; |
| 117 | + } |
81 | 118 | } |
82 | 119 | } |
0 commit comments