Repository: TheAlgorithms/Java
Pull request #5902 (2024-10-19 15:08:33)

cleanup combination and combination test
Related to https://github.com/TheAlgorithms/Java/issues/5164

<!--
Thank you for your contribution!
In order to reduce the number of notifications sent to the maintainers, please:
- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests,
- make sure that all of the CI checks pass,
- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review
-->

<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.
- [x] All new code is formatted with `clang-format -i --style=file path/to/your/file.java`

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5902?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 66.79%. Comparing base [(`90d20b3`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/90d20b3a43642548ecc55e425517583080a81e2a?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms) to head [(`ab53016`)](https://app.codecov.io/gh/TheAlgorithms/Java/commit/ab53016fe7a99604816b8014b1c46d2e72fb7cea?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).
> Report is 89 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #5902      +/-   ##
============================================
+ Coverage     59.71%   66.79%   +7.07%     
- Complexity     3855     4501     +646     
============================================
  Files           561      611      +50     
  Lines         16017    16960     +943     
  Branches       3073     3276     +203     
============================================
+ Hits           9565    11328    +1763     
+ Misses         6047     5183     -864     
- Partials        405      449      +44     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/TheAlgorithms/Java/pull/5902?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=TheAlgorithms).


Patch:
diff --git a/src/main/java/com/thealgorithms/backtracking/Combination.java b/src/main/java/com/thealgorithms/backtracking/Combination.java
index bf2a672a..ecaf7428 100644
--- a/src/main/java/com/thealgorithms/backtracking/Combination.java
+++ b/src/main/java/com/thealgorithms/backtracking/Combination.java
@@ -1,6 +1,7 @@
 package com.thealgorithms.backtracking;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.TreeSet;
@@ -13,8 +14,6 @@ public final class Combination {
     private Combination() {
     }
 
-    private static int length;
-
     /**
      * Find all combinations of given array using backtracking
      * @param arr the array.
@@ -23,39 +22,45 @@ public final class Combination {
      * @return a list of all combinations of length n. If n == 0, return null.
      */
     public static <T> List<TreeSet<T>> combination(T[] arr, int n) {
+        if (n < 0) {
+            throw new IllegalArgumentException("The combination length cannot be negative.");
+        }
+
         if (n == 0) {
-            return null;
+            return Collections.emptyList();
         }
-        length = n;
         T[] array = arr.clone();
         Arrays.sort(array);
+
         List<TreeSet<T>> result = new LinkedList<>();
-        backtracking(array, 0, new TreeSet<T>(), result);
+        backtracking(array, n, 0, new TreeSet<T>(), result);
         return result;
     }
 
     /**
      * Backtrack all possible combinations of a given array
      * @param arr the array.
+     * @param n length of the combination
      * @param index the starting index.
      * @param currSet set that tracks current combination
      * @param result the list contains all combination.
      * @param <T> the type of elements in the array.
      */
-    private static <T> void backtracking(T[] arr, int index, TreeSet<T> currSet, List<TreeSet<T>> result) {
-        if (index + length - currSet.size() > arr.length) {
+    private static <T> void backtracking(T[] arr, int n, int index, TreeSet<T> currSet, List<TreeSet<T>> result) {
+        if (index + n - currSet.size() > arr.length) {
             return;
         }
-        if (length - 1 == currSet.size()) {
+        if (currSet.size() == n - 1) {
             for (int i = index; i < arr.length; i++) {
                 currSet.add(arr[i]);
-                result.add((TreeSet<T>) currSet.clone());
+                result.add(new TreeSet<>(currSet));
                 currSet.remove(arr[i]);
             }
+            return;
         }
         for (int i = index; i < arr.length; i++) {
             currSet.add(arr[i]);
-            backtracking(arr, i + 1, currSet, result);
+            backtracking(arr, n, i + 1, currSet, result);
             currSet.remove(arr[i]);
         }
     }


Test patch:
diff --git a/src/test/java/com/thealgorithms/backtracking/CombinationTest.java b/src/test/java/com/thealgorithms/backtracking/CombinationTest.java
index 44edc307..a9d1163f 100644
--- a/src/test/java/com/thealgorithms/backtracking/CombinationTest.java
+++ b/src/test/java/com/thealgorithms/backtracking/CombinationTest.java
@@ -1,17 +1,28 @@
 package com.thealgorithms.backtracking;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.List;
+import java.util.Set;
 import java.util.TreeSet;
 import org.junit.jupiter.api.Test;
 
 public class CombinationTest {
 
+    @Test
+    void testNegativeElement() {
+        Integer[] array = {1, 2};
+        assertThrows(IllegalArgumentException.class, () -> { Combination.combination(array, -1); });
+    }
+
     @Test
     void testNoElement() {
         List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 0);
-        assertTrue(result == null);
+        assertNotNull(result);
+        assertEquals(0, result.size());
     }
 
     @Test
@@ -28,4 +39,13 @@ public class CombinationTest {
         assertTrue(arr[0] == 1);
         assertTrue(arr[1] == 2);
     }
+
+    @Test
+    void testCombinationsWithStrings() {
+        List<TreeSet<String>> result = Combination.combination(new String[] {"a", "b", "c"}, 2);
+        assertEquals(3, result.size());
+        assertTrue(result.contains(new TreeSet<>(Set.of("a", "b"))));
+        assertTrue(result.contains(new TreeSet<>(Set.of("a", "c"))));
+        assertTrue(result.contains(new TreeSet<>(Set.of("b", "c"))));
+    }
 }