diff --git a/algorithms-miscellaneous-1/pom.xml b/algorithms-miscellaneous-1/pom.xml
index fe670963c0..30130208f8 100644
--- a/algorithms-miscellaneous-1/pom.xml
+++ b/algorithms-miscellaneous-1/pom.xml
@@ -39,6 +39,11 @@
${org.assertj.core.version}
test
+
+ com.github.dpaukov
+ combinatoricslib3
+ 3.3.0
+
@@ -77,7 +82,7 @@
3.6.1
3.9.0
1.11
- 25.1-jre
+ 27.0.1-jre
\ No newline at end of file
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java
new file mode 100644
index 0000000000..40142ce940
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java
@@ -0,0 +1,29 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.commons.math3.util.CombinatoricsUtils;
+
+public class ApacheCommonsCombinationGenerator {
+
+ private static final int N = 6;
+ private static final int R = 3;
+
+ /**
+ * Print all combinations of r elements from a set
+ * @param n - number of elements in set
+ * @param r - number of elements in selection
+ */
+ public static void generate(int n, int r) {
+ Iterator iterator = CombinatoricsUtils.combinationsIterator(n, r);
+ while (iterator.hasNext()) {
+ final int[] combination = iterator.next();
+ System.out.println(Arrays.toString(combination));
+ }
+ }
+
+ public static void main(String[] args) {
+ generate(N, R);
+ }
+}
\ No newline at end of file
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java
new file mode 100644
index 0000000000..0afdeefb8b
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java
@@ -0,0 +1,13 @@
+package com.baeldung.algorithms.combination;
+
+import org.paukov.combinatorics3.Generator;
+
+public class CombinatoricsLibCombinationGenerator {
+
+ public static void main(String[] args) {
+ Generator.combination(0, 1, 2, 3, 4, 5)
+ .simple(3)
+ .stream()
+ .forEach(System.out::println);
+ }
+}
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java
new file mode 100644
index 0000000000..d2783881ba
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java
@@ -0,0 +1,17 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+public class GuavaCombinationsGenerator {
+
+ public static void main(String[] args) {
+
+ Set> combinations = Sets.combinations(ImmutableSet.of(0, 1, 2, 3, 4, 5), 3);
+ System.out.println(combinations.size());
+ System.out.println(Arrays.toString(combinations.toArray()));
+ }
+}
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java
new file mode 100644
index 0000000000..676d2f41e3
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class IterativeCombinationGenerator {
+
+ private static final int N = 5;
+ private static final int R = 2;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n the number of elements in input set
+ * @param r the number of elements in a combination
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ int[] combination = new int[r];
+
+ // initialize with lowest lexicographic combination
+ for (int i = 0; i < r; i++) {
+ combination[i] = i;
+ }
+
+ while (combination[r - 1] < n) {
+ combinations.add(combination.clone());
+
+ // generate next combination in lexicographic order
+ int t = r - 1;
+ while (t != 0 && combination[t] == n - r + t) {
+ t--;
+ }
+ combination[t]++;
+ for (int i = t + 1; i < r; i++) {
+ combination[i] = combination[i - 1] + 1;
+ }
+ }
+
+ return combinations;
+ }
+
+ public static void main(String[] args) {
+ IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ System.out.println(combinations.size());
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ }
+}
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java
new file mode 100644
index 0000000000..52305b8c2f
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java
@@ -0,0 +1,53 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SelectionRecursiveCombinationGenerator {
+
+ private static final int N = 6;
+ private static final int R = 3;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n - number of elements in input set
+ * @param r - number of elements to be chosen
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n - 1, 0);
+ return combinations;
+ }
+
+ /**
+ * Choose elements from set by recursing over elements selected
+ * @param combinations - List to store generated combinations
+ * @param data - current combination
+ * @param start - starting element of remaining set
+ * @param end - last element of remaining set
+ * @param index - number of elements chosen so far.
+ */
+ private void helper(List combinations, int data[], int start, int end, int index) {
+ if (index == data.length) {
+ int[] combination = data.clone();
+ combinations.add(combination);
+ } else {
+ int max = Math.min(end, end + 1 - data.length + index);
+ for (int i = start; i <= max; i++) {
+ data[index] = i;
+ helper(combinations, data, i + 1, end, index + 1);
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
+ }
+}
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
new file mode 100644
index 0000000000..a73447b31d
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
@@ -0,0 +1,50 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SetRecursiveCombinationGenerator {
+
+ private static final int N = 5;
+ private static final int R = 2;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n - number of elements in set
+ * @param r - number of elements in selection
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n-1, 0);
+ return combinations;
+ }
+
+ /**
+ * @param combinations - List to contain the generated combinations
+ * @param data - List of elements in the selection
+ * @param start - index of the starting element in the remaining set
+ * @param end - index of the last element in the set
+ * @param index - number of elements selected so far
+ */
+ private void helper(List combinations, int data[], int start, int end, int index) {
+ if (index == data.length) {
+ int[] combination = data.clone();
+ combinations.add(combination);
+ } else if (start <= end) {
+ data[index] = start;
+ helper(combinations, data, start + 1, end, index + 1);
+ helper(combinations, data, start + 1, end, index);
+ }
+ }
+
+ public static void main(String[] args) {
+ SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
+ }
+}
diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java b/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java
new file mode 100644
index 0000000000..987b6ddae6
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.algorithms.combination;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+public class CombinationUnitTest {
+
+ private static final int N = 5;
+ private static final int R = 3;
+ private static final int nCr = 10;
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingSetRecursiveAlgorithm_thenExpectedCount() {
+ SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingSelectionRecursiveAlgorithm_thenExpectedCount() {
+ SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingIterativeAlgorithm_thenExpectedCount() {
+ IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+}