Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all subsets of length k in an array

Given a set {1,2,3,4,5...n} of n elements, we need to find all subsets of length k .

For example, if n = 4 and k = 2, the output would be {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}.

I am not even able to figure out how to start. We don't have to use the inbuilt library functions like next_permutation etc.

Need the algorithm and implementation in either C/C++ or Java.

like image 259
h4ck3d Avatar asked Sep 22 '12 22:09

h4ck3d


People also ask

How many subsets of K is in a set?

In other words, the number of subsets of size k of an n-set is (n k ) . Page 12 Property 3 says that binomial coefficients can be calculated recursively, using Pas- cal's triangle, where each entry is the sum of the two adjacent ones in the up- per row.

How do you find all the subsets of a set?

If a set has “n” elements, then the number of subset of the given set is 2n and the number of proper subsets of the given subset is given by 2n-1. Consider an example, If set A has the elements, A = {a, b}, then the proper subset of the given subset are { }, {a}, and {b}.

What are subsets of an array?

A subset of an array is similar to a subset of a set. We print all the possible combinations of the array using each element, (including phi) which means no elements of the array.


2 Answers

Recursion is your friend for this task.

For each element - "guess" if it is in the current subset, and recursively invoke with the guess and a smaller superset you can select from. Doing so for both the "yes" and "no" guesses - will result in all possible subsets.
Restraining yourself to a certain length can be easily done in a stop clause.

Java code:

private static void getSubsets(List<Integer> superSet, int k, int idx, Set<Integer> current,List<Set<Integer>> solution) {     //successful stop clause     if (current.size() == k) {         solution.add(new HashSet<>(current));         return;     }     //unseccessful stop clause     if (idx == superSet.size()) return;     Integer x = superSet.get(idx);     current.add(x);     //"guess" x is in the subset     getSubsets(superSet, k, idx+1, current, solution);     current.remove(x);     //"guess" x is not in the subset     getSubsets(superSet, k, idx+1, current, solution); }  public static List<Set<Integer>> getSubsets(List<Integer> superSet, int k) {     List<Set<Integer>> res = new ArrayList<>();     getSubsets(superSet, k, 0, new HashSet<Integer>(), res);     return res; } 

Invoking with:

List<Integer> superSet = new ArrayList<>(); superSet.add(1); superSet.add(2); superSet.add(3); superSet.add(4); System.out.println(getSubsets(superSet,2)); 

Will yield:

[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] 
like image 73
amit Avatar answered Sep 19 '22 13:09

amit


Use a bit vector representation of the set, and use an algorithm similar to what std::next_permutation does on 0000.1111 (n-k zeroes, k ones). Each permutation corresponds to a subset of size k.

like image 22
Simple Avatar answered Sep 20 '22 13:09

Simple