This is a Facebook interview question I came across at an online portal.
Given a set S, find all the maximal subsets whose sum <= k. For example, if S = {1, 2, 3, 4,
Algorithm is the following:
Working solution on Java is below:
public class Test {
/**
* Assuming alphabet[] is already sorted in increasing order
*/
public static void printMaximalSubSetsToSum(int[] alphabet, int sum) {
if (alphabet == null || alphabet.length == 0) {
return;
}
if (alphabet[0] > sum) {
// no sense to search, since smallest element in array already bigger than sum
return;
} else if (alphabet[0] == sum) {
Set subSet = new HashSet<>();
subSet.add(alphabet[0]);
printSubset(subSet);
}
Set subSet = new HashSet<>();
processMaximalSubSetToSum(alphabet, sum, 0, 0, subSet);
}
private static void processMaximalSubSetToSum(int[] alphabet, int sum, int sumSoFar, int startFrom, Set subSet) {
if (startFrom >= alphabet.length) {
if (isMaximalSubSet(alphabet, subSet, sum - sumSoFar)) {
printSubset(subSet);
}
return;
}
for (int i = startFrom; i < alphabet.length; i++) {
int newSum = sumSoFar + alphabet[i];
if (newSum > sum) {
if (isMaximalSubSet(alphabet, subSet, sum - sumSoFar)) {
printSubset(subSet);
}
return;
} else {
subSet.add(alphabet[i]);
if (newSum == sum) {
printSubset(subSet);
} else {
processMaximalSubSetToSum(alphabet, sum, newSum, i + 1, subSet);
}
subSet.remove(alphabet[i]);
}
}
}
private static boolean isMaximalSubSet(int[] alphabet, Set subSet, int diff) {
// search first mismatch element between alphabet and current SubSet
Iterator it = subSet.iterator();
int i = 0;
while (it.hasNext()) {
if (it.next() != alphabet[i]) {
break;
}
i++;
}
return i >= alphabet.length || alphabet[i] > diff;
}
private static void printSubset(Set subset) {
System.out.println(subset);
}
public static void main(String[] args) throws java.lang.Exception {
//printMaximalSubSetsToSum(new int[]{1, 2, 3, 4, 5}, 7);
// Correct output is: {1, 2, 3}; {1, 2, 4}; {1, 5}; {2, 5}; {3, 4}
}
}