Finding all possible combinations of numbers to reach a given sum

前端 未结 30 3017
一个人的身影
一个人的身影 2020-11-21 06:39

How would you go about testing all possible combinations of additions from a given set N of numbers so they add up to a given final number?

A brief exam

相关标签:
30条回答
  • 2020-11-21 07:06
    function solve(n){
        let DP = [];
    
         DP[0] = DP[1] = DP[2] = 1;
         DP[3] = 2;
    
        for (let i = 4; i <= n; i++) {
          DP[i] = DP[i-1] + DP[i-3] + DP[i-4];
        }
        return DP[n]
    }
    
    console.log(solve(5))
    

    This is a Dynamic Solution for JS to tell how many ways anyone can get the certain sum. This can be the right solution if you think about time and space complexity.

    0 讨论(0)
  • 2020-11-21 07:08

    This can be used to print all the answers as well

    public void recur(int[] a, int n, int sum, int[] ans, int ind) {
        if (n < 0 && sum != 0)
            return;
        if (n < 0 && sum == 0) {
            print(ans, ind);
            return;
        }
        if (sum >= a[n]) {
            ans[ind] = a[n];
            recur(a, n - 1, sum - a[n], ans, ind + 1);
        }
        recur(a, n - 1, sum, ans, ind);
    }
    
    public void print(int[] a, int n) {
        for (int i = 0; i < n; i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }
    

    Time Complexity is exponential. Order of 2^n

    0 讨论(0)
  • 2020-11-21 07:08
    import java.util.*;
    
    public class Main{
    
         int recursionDepth = 0;
         private int[][] memo;
    
         public static void main(String []args){
             int[] nums = new int[] {5,2,4,3,1};
             int N = nums.length;
             Main main =  new Main();
             main.memo = new int[N+1][N+1];
             main._findCombo(0, N-1,nums, 8, 0, new LinkedList() );
             System.out.println(main.recursionDepth);
         }
    
    
           private void _findCombo(
               int from,
               int to,
               int[] nums,
               int targetSum,
               int currentSum,
               LinkedList<Integer> list){
    
                if(memo[from][to] != 0) {
                    currentSum = currentSum + memo[from][to];
                }
    
                if(currentSum > targetSum) {
                    return;
                }
    
                if(currentSum ==  targetSum) {
                    System.out.println("Found - " +list);
                    return;
                }
    
                recursionDepth++;
    
               for(int i= from ; i <= to; i++){
                   list.add(nums[i]);
                   memo[from][i] = currentSum + nums[i];
                   _findCombo(i+1, to,nums, targetSum, memo[from][i], list);
                    list.removeLast();
               }
    
         }
    }
    
    0 讨论(0)
  • 2020-11-21 07:10

    A Javascript version:

    function subsetSum(numbers, target, partial) {
      var s, n, remaining;
    
      partial = partial || [];
    
      // sum partial
      s = partial.reduce(function (a, b) {
        return a + b;
      }, 0);
    
      // check if the partial sum is equals to target
      if (s === target) {
        console.log("%s=%s", partial.join("+"), target)
      }
    
      if (s >= target) {
        return;  // if we reach the number why bother to continue
      }
    
      for (var i = 0; i < numbers.length; i++) {
        n = numbers[i];
        remaining = numbers.slice(i + 1);
        subsetSum(remaining, target, partial.concat([n]));
      }
    }
    
    subsetSum([3,9,8,4,5,7,10],15);
    
    // output:
    // 3+8+4=15
    // 3+5+7=15
    // 8+7=15
    // 5+10=15

    0 讨论(0)
  • 2020-11-21 07:11

    Here is a better version with better output formatting and C++ 11 features:

    void subset_sum_rec(std::vector<int> & nums, const int & target, std::vector<int> & partialNums) 
    {
        int currentSum = std::accumulate(partialNums.begin(), partialNums.end(), 0);
        if (currentSum > target)
            return;
        if (currentSum == target) 
        {
            std::cout << "sum([";
            for (auto it = partialNums.begin(); it != std::prev(partialNums.end()); ++it)
                cout << *it << ",";
            cout << *std::prev(partialNums.end());
            std::cout << "])=" << target << std::endl;
        }
        for (auto it = nums.begin(); it != nums.end(); ++it) 
        {
            std::vector<int> remaining;
            for (auto it2 = std::next(it); it2 != nums.end(); ++it2)
                remaining.push_back(*it2);
    
            std::vector<int> partial = partialNums;
            partial.push_back(*it);
            subset_sum_rec(remaining, target, partial);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:12

    This is similar to a coin change problem

    public class CoinCount 
    {   
    public static void main(String[] args)
    {
        int[] coins={1,4,6,2,3,5};
        int count=0;
    
        for (int i=0;i<coins.length;i++)
        {
            count=count+Count(9,coins,i,0);
        }
        System.out.println(count);
    }
    
    public static int Count(int Sum,int[] coins,int index,int curSum)
    {
        int count=0;
    
        if (index>=coins.length)
            return 0;
    
        int sumNow=curSum+coins[index];
        if (sumNow>Sum)
            return 0;
        if (sumNow==Sum)
            return 1;
    
        for (int i= index+1;i<coins.length;i++)
            count+=Count(Sum,coins,i,sumNow);
    
        return count;       
    }
    }
    
    0 讨论(0)
提交回复
热议问题