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

后端 未结 6 1446
感动是毒
感动是毒 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:05

    An old question but still an interesting one.

    Here's a recursive Java 8 solution, with a "permutational" approach.

    Optimized for cleaner and shorter code rather than performance -- for example the sorting and pruning would only need to take place once.

    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.Ordering;
    import java.util.*;
    import java.util.stream.Collectors;
    
    public class SubsetFinder {
        public List> findSubsets(List input, int k) {
            List> listOfLists = new ArrayList<>();
            List copy = Ordering.natural().sortedCopy(input);
    
            while (!copy.isEmpty()) {
                int v = copy.remove(copy.size() - 1);
                if (v == k || (copy.isEmpty() && v <= k)) {
                    // No need to look for subsets if the element itself == k, or
                    // if it's the last remaining element and <= k.
                    listOfLists.add(new ArrayList<>(Arrays.asList(v)));
                } else if (v < k) {
                    findSubsets(copy, k - v).forEach(subList -> {
                        subList.add(v);
                        listOfLists.add(subList);
                    });
                }
            }
    
            // Prune sets which are duplicates or subsets of other sets
            return listOfLists.stream().filter(
                    candidate -> listOfLists.stream().noneMatch(
                            lol -> candidate != lol && lol.containsAll(candidate)
                    )
            ).collect(Collectors.toList());
        }
    }
    

    To test it:

    public static void main(String[] args) {
        new SubsetFinder()
            .findSubsets(ImmutableList.of(1, 2, 3, 4, 5), 7)
            .forEach(System.out::println);
    }
    

提交回复
热议问题