Find all combinations of a given set of integers summing up to a given sum

前端 未结 3 1977
面向向阳花
面向向阳花 2021-01-07 14:00

I am looking for an answer to the following problem.

Given a set of integers (no duplicates) and a sum, find all possible combinations of the set\'s elements summing

相关标签:
3条回答
  • 2021-01-07 14:33

    This is known as the Change-making problem and is a classic example in dynamic programming.

    Some earlier answers have calculated the total count of solutions, whilst the question has asked for an enumeration of the possible solutions.

    You haven't tagged your question with a language, so here's an implementation in Python. Adapt it to whatever language you please by using your language's "bag" datatype (n.b. the Counter is Python's "bag").

    from collections import Counter
    
    def ways(total, coins):
        ways = [[Counter()]] + [[] for _ in range(total)]
        for coin in coins:
            for i in range(coin, total + 1):
                ways[i] += [way + Counter({coin: 1}) for way in ways[i-coin]]
        return ways[total]
    

    The output datatype is a list of bags. Demo usage for printing them:

    >>> from __future__ import print_function  # for Python 2 compatibility
    >>> for way in ways(total=10, coins=(2,3,5)):
    ...     coins = (coin for coin,count in way.items() for _ in range(count))
    ...     print(*coins)
    ... 
    2 2 2 2 2
    2 2 3 3
    2 3 5
    5 5
    
    0 讨论(0)
  • 2021-01-07 14:36

    Here is a Haskell function that calculates the answer:

    partitions 0 xs = [[]]
    partitions _ [] = []
    partitions n (xxs@(x:xs)) | n < 0 = []
                              | otherwise = (map (x:) (partitions (n-x) xxs)) ++ partitions n xs
    

    Examples:

    *Main>  partitions 1 [1]
    [[1]]
    *Main>  partitions 5 [1..5]
    [[1,1,1,1,1],[1,1,1,2],[1,1,3],[1,2,2],[1,4],[2,3],[5]]
    *Main> length $ partitions 10 [1..10]
    42
    *Main> length $ partitions 20 [1..20]
    627
    *Main> length $ partitions 40 [1..40]
    37338
    *Main> partitions 10 [1,2,4]
    [[1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,2],[1,1,1,1,1,1,2,2],[1,1,1,1,1,1,4],[1,1,1,1,2,2,2],[1,1,1,1,2,4],[1,1,2,2,2,2],[1,1,2,2,4],[1,1,4,4],[2,2,2,2,2],[2,2,2,4],[2,4,4]]
    

    Semi-live demo

    0 讨论(0)
  • 2021-01-07 14:48

    Solution complexity:

    • time: O(n*M)
    • memory: O(M),

    where M is value of sum, n is set size

    int numberOfSums(Set<Integer> values, int sum) {
        // sumCount[i] -> number of ways to get sum == i 
        int sumCount[] = new int[sum+1];
        sumCount[0] = 1;
        for(int v : values) {
            for(int i=0; i<=sum-v; ++i)
                sumCount[i+v] += sumCount[i];
        }
        return sumCount[sum];
    }
    
    0 讨论(0)
提交回复
热议问题