mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-12-19 07:00:35 +08:00
add CombinationSum and test (#6725)
* add CombinationSum and test * Format array and list literals in CombinationSumTest * Fix sorting comparator in CombinationSumTest * Refactor CombinationSum for better handling and clarity Updated combinationSum method to handle null or empty candidates and improved variable naming for clarity. * Fix sorting comparator in CombinationSumTest * Update CombinationSumTest.java * Fix sorting comparator for list of integers * Fix formatting issues in CombinationSum class * Change CombinationSum class to final * Refactor norm method to accept Iterable instead of List * Remove unnecessary whitespace in CombinationSumTest
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/** Backtracking: pick/not-pick with reuse of candidates. */
|
||||
public final class CombinationSum {
|
||||
private CombinationSum() {
|
||||
throw new UnsupportedOperationException("Utility class");
|
||||
}
|
||||
|
||||
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
|
||||
List<List<Integer>> results = new ArrayList<>();
|
||||
if (candidates == null || candidates.length == 0) {
|
||||
return results;
|
||||
}
|
||||
|
||||
// Sort to help with pruning duplicates and early termination
|
||||
Arrays.sort(candidates);
|
||||
backtrack(candidates, target, 0, new ArrayList<>(), results);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void backtrack(int[] candidates, int remaining, int start, List<Integer> combination, List<List<Integer>> results) {
|
||||
if (remaining == 0) {
|
||||
// Found valid combination; add a copy
|
||||
results.add(new ArrayList<>(combination));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = start; i < candidates.length; i++) {
|
||||
int candidate = candidates[i];
|
||||
|
||||
// If candidate is greater than remaining target, further candidates (sorted) will also be too big
|
||||
if (candidate > remaining) {
|
||||
break;
|
||||
}
|
||||
|
||||
// include candidate
|
||||
combination.add(candidate);
|
||||
// Because we can reuse the same element, we pass i (not i + 1)
|
||||
backtrack(candidates, remaining - candidate, i, combination, results);
|
||||
// backtrack: remove last
|
||||
combination.remove(combination.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class CombinationSumTest {
|
||||
private static List<List<Integer>> norm(Iterable<List<Integer>> x) {
|
||||
List<List<Integer>> y = new ArrayList<>();
|
||||
for (var p : x) {
|
||||
var q = new ArrayList<>(p);
|
||||
q.sort(Integer::compare);
|
||||
y.add(q);
|
||||
}
|
||||
y.sort(Comparator.<List<Integer>>comparingInt(List::size).thenComparing(Object::toString));
|
||||
return y;
|
||||
}
|
||||
|
||||
@Test
|
||||
void sample() {
|
||||
int[] candidates = {2, 3, 6, 7};
|
||||
int target = 7;
|
||||
var expected = List.of(List.of(2, 2, 3), List.of(7));
|
||||
assertEquals(norm(expected), norm(CombinationSum.combinationSum(candidates, target)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user