Skip to content

Commit 4d7e8b5

Browse files
authored
Merge branch 'master' into refactor/counting_sort
2 parents 0be0b6c + f83bb65 commit 4d7e8b5

File tree

2 files changed

+47
-52
lines changed

2 files changed

+47
-52
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,42 @@
11
package com.thealgorithms.backtracking;
22

3+
import java.util.ArrayList;
34
import java.util.List;
4-
import java.util.TreeSet;
55

66
/**
7-
* Finds all permutations of 1...n of length k
8-
* @author TheClerici (<a href="https://github.com/TheClerici">git-TheClerici</a>)
7+
* Finds all combinations of 0...n-1 of length k
98
*/
109
public final class ArrayCombination {
1110
private ArrayCombination() {
1211
}
13-
private static int length;
1412

1513
/**
16-
* Find all combinations of 1..n by creating an array and using backtracking in Combination.java
17-
* @param n max value of the array.
18-
* @param k length of combination
19-
* @return a list of all combinations of length k. If k == 0, return null.
14+
* Finds all combinations of length k of 0..n-1 using backtracking.
15+
*
16+
* @param n Number of the elements.
17+
* @param k Length of the combination.
18+
* @return A list of all combinations of length k.
2019
*/
21-
public static List<TreeSet<Integer>> combination(int n, int k) {
22-
if (n <= 0) {
23-
return null;
20+
public static List<List<Integer>> combination(int n, int k) {
21+
if (n < 0 || k < 0 || k > n) {
22+
throw new IllegalArgumentException("Wrong input.");
2423
}
25-
length = k;
26-
Integer[] arr = new Integer[n];
27-
for (int i = 1; i <= n; i++) {
28-
arr[i - 1] = i;
24+
25+
List<List<Integer>> combinations = new ArrayList<>();
26+
combine(combinations, new ArrayList<>(), 0, n, k);
27+
return combinations;
28+
}
29+
30+
private static void combine(List<List<Integer>> combinations, List<Integer> current, int start, int n, int k) {
31+
if (current.size() == k) { // Base case: combination found
32+
combinations.add(new ArrayList<>(current)); // Copy to avoid modification
33+
return;
34+
}
35+
36+
for (int i = start; i < n; i++) {
37+
current.add(i);
38+
combine(combinations, current, i + 1, n, k);
39+
current.removeLast(); // Backtrack
2940
}
30-
return Combination.combination(arr, length);
3141
}
3242
}
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,36 @@
11
package com.thealgorithms.backtracking;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertNull;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
55

6+
import com.thealgorithms.maths.BinomialCoefficient;
7+
import java.util.ArrayList;
68
import java.util.List;
7-
import java.util.TreeSet;
8-
import org.junit.jupiter.api.Test;
9+
import java.util.stream.Stream;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.Arguments;
12+
import org.junit.jupiter.params.provider.MethodSource;
913

1014
public class ArrayCombinationTest {
11-
12-
@Test
13-
void testNBeingZeroOrLess() {
14-
List<TreeSet<Integer>> zeroResult = ArrayCombination.combination(0, 1);
15-
List<TreeSet<Integer>> negativeResult = ArrayCombination.combination(-1, 1);
16-
assertNull(zeroResult);
17-
assertNull(negativeResult);
18-
}
19-
20-
@Test
21-
void testNoLengthElement() {
22-
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 0);
23-
assertNull(result);
15+
@ParameterizedTest
16+
@MethodSource("regularInputs")
17+
void testCombination(int n, int k, List<List<Integer>> expected) {
18+
assertEquals(expected.size(), BinomialCoefficient.binomialCoefficient(n, k));
19+
assertEquals(expected, ArrayCombination.combination(n, k));
2420
}
2521

26-
@Test
27-
void testLengthOne() {
28-
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 1);
29-
assert result != null;
30-
assertEquals(1, result.get(0).iterator().next());
31-
assertEquals(2, result.get(1).iterator().next());
22+
@ParameterizedTest
23+
@MethodSource("wrongInputs")
24+
void testCombinationThrows(int n, int k) {
25+
assertThrows(IllegalArgumentException.class, () -> ArrayCombination.combination(n, k));
3226
}
3327

34-
@Test
35-
void testLengthTwo() {
36-
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 2);
37-
assert result != null;
38-
Integer[] arr = result.get(0).toArray(new Integer[2]);
39-
assertEquals(1, arr[0]);
40-
assertEquals(2, arr[1]);
28+
private static Stream<Arguments> regularInputs() {
29+
return Stream.of(Arguments.of(0, 0, List.of(new ArrayList<Integer>())), Arguments.of(1, 0, List.of(new ArrayList<Integer>())), Arguments.of(1, 1, List.of(List.of(0))), Arguments.of(3, 0, List.of(new ArrayList<Integer>())), Arguments.of(3, 1, List.of(List.of(0), List.of(1), List.of(2))),
30+
Arguments.of(4, 2, List.of(List.of(0, 1), List.of(0, 2), List.of(0, 3), List.of(1, 2), List.of(1, 3), List.of(2, 3))));
4131
}
4232

43-
@Test
44-
void testLengthFive() {
45-
List<TreeSet<Integer>> result = ArrayCombination.combination(10, 5);
46-
assert result != null;
47-
Integer[] arr = result.get(0).toArray(new Integer[5]);
48-
assertEquals(1, arr[0]);
49-
assertEquals(5, arr[4]);
33+
private static Stream<Arguments> wrongInputs() {
34+
return Stream.of(Arguments.of(-1, 0), Arguments.of(0, -1), Arguments.of(2, 100));
5035
}
5136
}

0 commit comments

Comments
 (0)