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