package util; import java.util.Arrays; import java.util.HashSet; import java.util.stream.IntStream; public class Combinations { private static HashSet> result = new HashSet<>(); /* arr[] ---> Input Array data[] ---> Temporary array to store current combination start & end ---> Staring and Ending indexes in arr[] index ---> Current index in data[] r ---> Size of a combination to be printed */ static void combinationUtil(int arr[], Integer data[], int start, int end, int index, int combinationLength) { // Current combination is ready to be printed, print it if (index == combinationLength) { result.add(new HashSet<>(Arrays.asList(data))); return; } // replace index with all possible elements. The condition // "end-i+1 >= r-index" makes sure that including one element // at index will make a combination with remaining elements // at remaining positions for (int i = start; i <= end && end - i + 1 >= combinationLength - index; i++) { data[index] = arr[i]; combinationUtil(arr, data, i + 1, end, index + 1, combinationLength); } } public static HashSet> generateIndices(int maxNOfIndices) { result = new HashSet<>(); int[] arr = IntStream.range(1, maxNOfIndices).toArray(); for (int i = 1; i < maxNOfIndices - 1; i++) { // A temporary array to store all combination one by one combinationUtil(arr, new Integer[i], 0, arr.length - 1, 0, i); } // also add an empty one for X.... (all of this type) result.add(new HashSet<>()); return result; } }