diff --git a/algorithms-miscellaneous-1/pom.xml b/algorithms-miscellaneous-1/pom.xml
index fe670963c0..0d528023d6 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
+
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..4ec36927fa
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java
@@ -0,0 +1,17 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.commons.math3.util.CombinatoricsUtils;
+
+public class ApacheCommonsCombinationGenerator {
+
+ public static void main(String[] args) {
+ Iterator iterator = CombinatoricsUtils.combinationsIterator(5, 3);
+ while (iterator.hasNext()) {
+ final int[] combination = iterator.next();
+ System.out.println(Arrays.toString(combination));
+ }
+ }
+}
\ 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..a0c7222717
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java
@@ -0,0 +1,45 @@
+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;
+
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ int[] combination = new int[r];
+
+ for (int i = 0; i < r; i++) {
+ combination[i] = i;
+ }
+
+ while (combination[r - 1] < n) {
+ combinations.add(combination.clone());
+
+ 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..400042b137
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java
@@ -0,0 +1,39 @@
+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;
+
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n - 1, 0);
+ return combinations;
+ }
+
+ 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);
+ 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/SetRecursiveCombinationGenerator.java b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
new file mode 100644
index 0000000000..60c1c229b9
--- /dev/null
+++ b/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
@@ -0,0 +1,38 @@
+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 = 6;
+ private static final int R = 3;
+
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n - 1, 0, r);
+ return combinations;
+ }
+
+ private void helper(List combinations, int data[], int start, int end, int index, int r) {
+ 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, r);
+ helper(combinations, data, start + 1, end, index, r);
+ }
+ }
+
+ public static void main(String[] args) {
+ SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
+ 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/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());
+ }
+}