【问题标题】:Finding all possible combinations of numbers to reach a given sum找到所有可能的数字组合以达到给定的总和
【发布时间】:2011-06-05 15:54:10
【问题描述】:

您将如何测试给定集合N 中所有可能的加法组合,以便它们加起来为给定的最终数字?

一个简单的例子:

  • 要添加的数字集:N = {1,5,22,15,0,...}
  • 想要的结果:12345

【问题讨论】:

  • 维基百科的文章 (en.wikipedia.org/wiki/Subset_sum_problem) 甚至提到这个问题是对 NP 完全问题类的一个很好的介绍。
  • 我们可以多次使用原始集合的相同元素吗?例如,如果输入是 {1,2,3,5} 并且目标是 10,那么 5 + 5 = 10 是可接受的解决方案吗?
  • 只有一次。如果要重复一个整数,它会显示为一个新元素。
  • stackoverflow.com/a/64380474/585411 展示了如何使用动态编程来避免在生成答案时进行不必要的工作。

标签: algorithm search language-agnostic combinations subset-sum


【解决方案1】:
func sum(array : [Int]) -> Int{
    var sum = 0
    array.forEach { (item) in
        sum = item + sum
    }
    return sum
}
func susetNumbers(array :[Int], target : Int, subsetArray: [Int],result : inout [[Int]]) -> [[Int]]{
    let s = sum(array: subsetArray)
    if(s == target){
        print("sum\(subsetArray) = \(target)")
        result.append(subsetArray)
    }
    for i in 0..<array.count{
        let n = array[i]
        let remaning = Array(array[(i+1)..<array.count])
        susetNumbers(array: remaning, target: target, subsetArray: subsetArray + [n], result: &result)
        
    }
    return result
}

 var resultArray = [[Int]]()
    let newA = susetNumbers(array: [1,2,3,4,5], target: 5, subsetArray: [],result:&resultArray)
    print(resultArray)

【讨论】:

    【解决方案2】:

    针对这个问题的一种迭代 C++ 堆栈解决方案。与其他一些迭代解决方案不同,它不会制作不必要的中间序列副本。

    #include <vector>
    #include <iostream>
    
    // Given a positive integer, return all possible combinations of
    // positive integers that sum up to it.
    
    std::vector<std::vector<int>> print_all_sum(int target){
        std::vector<std::vector<int>> output;
        std::vector<int> stack;
    
        int curr_min = 1;
        int sum = 0;
        while (curr_min < target) {
            sum += curr_min;
            if (sum >= target) {
                if (sum == target) {
                    output.push_back(stack); // make a copy
                    output.back().push_back(curr_min);
                }
                sum -= curr_min + stack.back();
                curr_min = stack.back() + 1;
                stack.pop_back();
            } else {
                stack.push_back(curr_min);
            }
        }
    
        return output;
    }
    
    int main()
    {
        auto vvi = print_all_sum(6);
    
        for (auto const& v: vvi) {
            for(auto const& i: v) {
            std::cout << i;
            }
            std::cout << "\n";
        }
    
        return 0;
    }
    

    输出print_all_sum(6):

    111111
    11112
    1113
    1122
    114
    123
    15
    222
    24
    33
    

    【讨论】:

      猜你喜欢
      • 2019-05-24
      • 2021-01-02
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多