Skip to content

Commit 5e78f73

Browse files
refactor 377
1 parent 13658a4 commit 5e78f73

File tree

3 files changed

+123
-42
lines changed

3 files changed

+123
-42
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ Your ideas/fixes/algorithms are more than welcome!
252252
|380|[Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_380.java)| O(n) | O(1)| Medium| Design, HashMap
253253
|379|[Design Phone Directory](https://leetcode.com/problems/design-phone-directory/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_379.java)| O(1)|O(n) | Medium|
254254
|378|[Kth Smallest Element in a Sorted Matrix](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_378.java)| O(logm*n) | O(1)| Medium| Binary Search
255-
|377|[Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_377.java)| O(?)|O(?) | Medium|
255+
|377|[Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_377.java)| O(n^2)|O(n) | Medium| DP
256256
|376|[Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_376.java)| O(n)|O(1) | Medium| DP, Greedy
257257
|375|[Guess Number Higher or Lower II](https://leetcode.com/problems/guess-number-higher-or-lower-ii/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_375.java)| O(n^2)|O(n^2) | Medium| DP
258258
|374|[Guess Number Higher or Lower](https://leetcode.com/problems/guess-number-higher-or-lower/)|[Solution](../master/src/main/java/com/fishercoder/solutions/_374.java)| O(logn)|O(1) | Easy| Binary Search
Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.fishercoder.solutions;
22

3-
import com.fishercoder.common.utils.CommonUtils;
4-
53
import java.util.ArrayList;
64
import java.util.Arrays;
75
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,
910
* find the number of possible combinations that add up to a positive integer target.
1011
1112
Example:
@@ -29,54 +30,90 @@
2930
Follow up:
3031
What if negative numbers are allowed in the given array?
3132
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+
3336
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);
4858
}
4959
}
5060
}
51-
return result[target];
5261
}
5362

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+
}
6175

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+
}
7285
}
7386
}
7487
}
7588

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+
}
81118
}
82119
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.fishercoder;
2+
3+
import com.fishercoder.solutions._377;
4+
import org.junit.BeforeClass;
5+
import org.junit.Test;
6+
7+
import static junit.framework.Assert.assertEquals;
8+
9+
public class _377Test {
10+
private static _377.Solution1 solution1;
11+
private static _377.Solution2 solution2;
12+
private static _377.Solution3 solution3;
13+
private static int[] nums;
14+
private static int target;
15+
16+
@BeforeClass
17+
public static void setup() {
18+
solution1 = new _377.Solution1();
19+
solution2 = new _377.Solution2();
20+
solution3 = new _377.Solution3();
21+
}
22+
23+
@Test
24+
public void test1() {
25+
nums = new int[]{1,2,3};
26+
target = 4;
27+
assertEquals(7, solution1.combinationSum4(nums, target));
28+
assertEquals(7, solution2.combinationSum4(nums, target));
29+
assertEquals(7, solution3.combinationSum4(nums, target));
30+
}
31+
32+
@Test
33+
public void test2() {
34+
nums = new int[]{4,2,1};
35+
target = 32;
36+
// assertEquals(39882198, solution1.combinationSum4(nums, target));//this results in MLE, so comment out
37+
38+
solution2.count = 0;//always have to reset this global variable to be zero before using it again
39+
assertEquals(39882198, solution2.combinationSum4(nums, target));
40+
41+
assertEquals(39882198, solution3.combinationSum4(nums, target));
42+
}
43+
44+
}

0 commit comments

Comments
 (0)