Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0dd3755

Browse files
author
Samuel Facchinello
committedJun 12, 2024·
refactor
1 parent 3ecd135 commit 0dd3755

File tree

2 files changed

+44
-42
lines changed

2 files changed

+44
-42
lines changed
 
Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,58 @@
11
package com.thealgorithms.backtracking;
22

3-
import java.util.Arrays;
4-
import java.util.LinkedList;
3+
import java.util.ArrayList;
54
import java.util.List;
65
import java.util.TreeSet;
76

87
/**
9-
* Finds all permutations of given array
10-
* @author Alan Piao (<a href="https://github.com/cpiao3">git-Alan Piao</a>)
8+
* Finds all combinations of a given array of unique elements.
119
*/
1210
public final class Combination {
1311
private Combination() {
1412
}
1513

16-
private static int length;
17-
1814
/**
19-
* Find all combinations of given array using backtracking
20-
* @param arr the array.
21-
* @param n length of combination
22-
* @param <T> the type of elements in the array.
23-
* @return a list of all combinations of length n. If n == 0, return null.
15+
* Finds all combinations of a given array of length n.
16+
* If n is 0, an empty list is returned.
17+
*
18+
* @param data the array of elements.
19+
* @param combinationSize the desired size of combinations.
20+
* @param <T> the type of elements in the array (assumed to be unique).
21+
* @return a list of all combinations of size `combinationSize`.
22+
* @throws IllegalArgumentException if combinationSize is negative.
2423
*/
25-
public static <T> List<TreeSet<T>> combination(T[] arr, int n) {
26-
if (n == 0) {
24+
public static <T> List<TreeSet<T>> combination(T[] data, int combinationSize) {
25+
if (combinationSize < 0) {
26+
throw new IllegalArgumentException("Combination size cannot be negative.");
27+
} else if (combinationSize == 0) {
2728
return null;
2829
}
29-
length = n;
30-
T[] array = arr.clone();
31-
Arrays.sort(array);
32-
List<TreeSet<T>> result = new LinkedList<>();
33-
backtracking(array, 0, new TreeSet<T>(), result);
34-
return result;
30+
31+
List<TreeSet<T>> combinations = new ArrayList<>();
32+
findCombinationsRecursive(data, 0, new ArrayList<>(), combinations, combinationSize);
33+
return combinations;
3534
}
3635

3736
/**
38-
* Backtrack all possible combinations of a given array
39-
* @param arr the array.
40-
* @param index the starting index.
41-
* @param currSet set that tracks current combination
42-
* @param result the list contains all combination.
37+
* Recursive helper function to find combinations using backtracking.
38+
*
39+
* @param data the array of elements.
40+
* @param startIndex the starting index for the current combination.
41+
* @param currentCombination the current combination being built.
42+
* @param combinations the list to store all found combinations.
43+
* @param combinationSize the desired size of combinations.
4344
* @param <T> the type of elements in the array.
4445
*/
45-
private static <T> void backtracking(T[] arr, int index, TreeSet<T> currSet, List<TreeSet<T>> result) {
46-
if (index + length - currSet.size() > arr.length) return;
47-
if (length - 1 == currSet.size()) {
48-
for (int i = index; i < arr.length; i++) {
49-
currSet.add(arr[i]);
50-
result.add((TreeSet<T>) currSet.clone());
51-
currSet.remove(arr[i]);
52-
}
46+
private static <T> void findCombinationsRecursive(T[] data, int startIndex, List<T> currentCombination, List<TreeSet<T>> combinations, int combinationSize) {
47+
if (currentCombination.size() == combinationSize) {
48+
combinations.add(new TreeSet<>(currentCombination)); // Deep copy to avoid modification
49+
return;
5350
}
54-
for (int i = index; i < arr.length; i++) {
55-
currSet.add(arr[i]);
56-
backtracking(arr, i + 1, currSet, result);
57-
currSet.remove(arr[i]);
51+
52+
for (int i = startIndex; i < data.length; i++) {
53+
currentCombination.add(data[i]);
54+
findCombinationsRecursive(data, i + 1, currentCombination, combinations, combinationSize);
55+
currentCombination.removeLast();
5856
}
5957
}
6058
}
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.thealgorithms.backtracking;
22

3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNull;
35
import static org.junit.jupiter.api.Assertions.assertTrue;
46

57
import java.util.List;
@@ -11,21 +13,23 @@ public class CombinationTest {
1113
@Test
1214
void testNoElement() {
1315
List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 0);
14-
assertTrue(result == null);
16+
assertNull(result);
1517
}
1618

1719
@Test
1820
void testLengthOne() {
1921
List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 1);
20-
assertTrue(result.get(0).iterator().next() == 1);
21-
assertTrue(result.get(1).iterator().next() == 2);
22+
assert result != null;
23+
assertEquals(1, (int) result.get(0).getFirst());
24+
assertEquals(2, (int) result.get(1).getFirst());
2225
}
2326

2427
@Test
2528
void testLengthTwo() {
2629
List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 2);
27-
Integer[] arr = result.get(0).toArray(new Integer[2]);
28-
assertTrue(arr[0] == 1);
29-
assertTrue(arr[1] == 2);
30+
assert result != null;
31+
Integer[] arr = result.getFirst().toArray(new Integer[2]);
32+
assertEquals(1, (int) arr[0]);
33+
assertEquals(2, (int) arr[1]);
3034
}
3135
}

0 commit comments

Comments
 (0)
Please sign in to comment.