|
1 | 1 | package com.thealgorithms.backtracking;
|
2 | 2 |
|
3 |
| -import java.util.Arrays; |
4 |
| -import java.util.LinkedList; |
| 3 | +import java.util.ArrayList; |
5 | 4 | import java.util.List;
|
6 | 5 | import java.util.TreeSet;
|
7 | 6 |
|
8 | 7 | /**
|
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. |
11 | 9 | */
|
12 | 10 | public final class Combination {
|
13 | 11 | private Combination() {
|
14 | 12 | }
|
15 | 13 |
|
16 |
| - private static int length; |
17 |
| - |
18 | 14 | /**
|
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. |
24 | 23 | */
|
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) { |
27 | 28 | return null;
|
28 | 29 | }
|
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; |
35 | 34 | }
|
36 | 35 |
|
37 | 36 | /**
|
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. |
43 | 44 | * @param <T> the type of elements in the array.
|
44 | 45 | */
|
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; |
53 | 50 | }
|
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(); |
58 | 56 | }
|
59 | 57 | }
|
60 | 58 | }
|
0 commit comments