Skip to content

Commit f0bfc2f

Browse files
add a solution for 698
1 parent 20fede4 commit f0bfc2f

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

src/main/java/com/fishercoder/solutions/_698.java

+54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.fishercoder.solutions;
22

3+
import java.util.Arrays;
4+
35
public class _698 {
46

57
public static class Solution1 {
@@ -38,4 +40,56 @@ private boolean canPartition(int[] nums, boolean[] visited, int startIndex, int
3840
}
3941
}
4042

43+
public static class Solution2 {
44+
/**
45+
* I'm glad that I figured out below solution completely on my own on 9/30/2021.
46+
* Backtracking is so beautiful!
47+
* <p>
48+
* Although not super concise, and I've added a sorting step, it's completely original.
49+
*/
50+
public boolean canPartitionKSubsets(int[] nums, int k) {
51+
Arrays.sort(nums);
52+
long sum = 0l;
53+
for (int num : nums) {
54+
sum += num;
55+
}
56+
int ave = (int) sum / k;
57+
if (sum % k != 0) {
58+
return false;
59+
}
60+
boolean[] used = new boolean[nums.length];
61+
int found = 0;
62+
for (int i = nums.length - 1; i >= 0; i--) {
63+
if (!used[i]) {
64+
used[i] = true;
65+
found += recursive(nums, used, ave, nums[i], i);
66+
}
67+
}
68+
return k == found;
69+
}
70+
71+
private int recursive(int[] nums, boolean[] used, int targetSum, int currSum, int currIndex) {
72+
if (currSum == targetSum) {
73+
return 1;
74+
} else if (currSum > targetSum) {
75+
used[currIndex] = false;
76+
return 0;
77+
} else {
78+
if (currIndex > 0) {
79+
for (int i = currIndex; i > 0; i--) {
80+
if (!used[i - 1]) {
81+
used[i - 1] = true;
82+
int found = recursive(nums, used, targetSum, currSum + nums[i - 1], i - 1);
83+
if (found == 1) {
84+
return found;
85+
}
86+
used[i - 1] = false;//this is the backtracking step: reset this number to be available if not found
87+
}
88+
}
89+
}
90+
return 0;
91+
}
92+
}
93+
}
94+
4195
}

src/test/java/com/fishercoder/_698Test.java

+54-1
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88

99
public class _698Test {
1010
private static _698.Solution1 solution1;
11+
private static _698.Solution2 solution2;
1112
private static int[] nums;
1213
private static int k;
1314

1415
@BeforeClass
1516
public static void setup() {
1617
solution1 = new _698.Solution1();
18+
solution2 = new _698.Solution2();
1719
}
1820

1921
@Test
@@ -25,8 +27,59 @@ public void test1() {
2527

2628
@Test
2729
public void test2() {
28-
nums = new int[]{-1,1,0,0};
30+
nums = new int[]{-1, 1, 0, 0};
2931
k = 4;
3032
assertEquals(false, solution1.canPartitionKSubsets(nums, k));
3133
}
34+
35+
@Test
36+
public void test3() {
37+
nums = new int[]{4, 3, 2, 3, 5, 2, 1};
38+
k = 4;
39+
assertEquals(true, solution2.canPartitionKSubsets(nums, k));
40+
}
41+
42+
@Test
43+
public void test4() {
44+
nums = new int[]{-1, 1, 0, 0};
45+
k = 4;
46+
assertEquals(false, solution2.canPartitionKSubsets(nums, k));
47+
}
48+
49+
@Test
50+
public void test5() {
51+
nums = new int[]{2, 2, 2, 2, 3, 4, 5};
52+
k = 4;
53+
assertEquals(false, solution2.canPartitionKSubsets(nums, k));
54+
}
55+
56+
@Test
57+
public void test6() {
58+
nums = new int[]{1, 2, 3, 4};
59+
k = 3;
60+
assertEquals(false, solution2.canPartitionKSubsets(nums, k));
61+
}
62+
63+
@Test
64+
public void test7() {
65+
nums = new int[]{1, 1, 1, 1, 2, 2, 2, 2};
66+
k = 3;
67+
assertEquals(true, solution2.canPartitionKSubsets(nums, k));
68+
}
69+
70+
@Test
71+
public void test8() {
72+
/**This test case clearly shows how backtracking plays out beautifully!*/
73+
nums = new int[]{3522, 181, 521, 515, 304, 123, 2512, 312, 922, 407, 146, 1932, 4037, 2646, 3871, 269};
74+
k = 5;
75+
assertEquals(true, solution2.canPartitionKSubsets(nums, k));
76+
}
77+
78+
@Test
79+
public void test9() {
80+
nums = new int[]{1, 2, 3, 5};
81+
k = 2;
82+
assertEquals(false, solution2.canPartitionKSubsets(nums, k));
83+
}
84+
3285
}

0 commit comments

Comments
 (0)