Given a set S, find all the maximal subsets whose sum <= k

后端 未结 6 1425
感动是毒
感动是毒 2021-02-14 21:52

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,

6条回答
  •  盖世英雄少女心
    2021-02-14 22:06

    Algorithm is the following:

    • Starting from empty subSet.
    • Cycle through original array from the beginning (assuming array is already sorted in ascending order) until currentSum is less or equal target sum.
    • If current element added to currentSum is less than target sum, adding to current subSet current element and running recursion starting from the next element.
    • Breaking current cycle if current sum exceed targetSum.
    • If we can't add more elements into current subSet, we checking if it is maximal and print it in this case.
    • To determine maximal subSets we can compare original array and current subSet element by element, searching for the first mismatch. If element at first mismatch index is greater than difference between currentSum and targetSum, subSet is maximal and should be printed.

    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}
        }
    
    }
    

提交回复
热议问题