【问题标题】:Given a bunch of integer numbers, please output all combination of all possible numbers by using plus operation only给定一堆整数,请仅使用加号运算输出所有可能数字的所有组合
【发布时间】:2019-04-23 15:42:21
【问题描述】:

给定一堆整数,请仅使用加号运算输出所有可能的数字的所有组合。

例如,

[10, 20] => [10, 20, 30]
[1, 2, 3] => [1, 2, 3, 4, 5, 6]
[10, 20, 20, 50] => [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

有人可以帮助我用 Java 实现这一点吗?

我已经尝试过,我认为它有效,但正在寻找其他解决方案。

public int[] getCoins2(int[] coins) {
    Set<Integer> result = new TreeSet<>();

    for (int coin : coins) {
        result.addAll(result.stream().map(value -> value + coin).collect(Collectors.toSet()));
        result.add(coin);
    }

    return toInt(result);
}

public int[] toInt(Set<Integer> set) {
    int[] a = new int[set.size()];

    int i = 0;

    for (Integer val : set) {
        a[i++] = val;
    }

    return a;
}

public static void main(String[] args) {

    CoinCombination combination = new CoinCombination();
    int[] coins = {10, 20, 20, 50, 100};

    System.out.println(Arrays.toString(combination.getCoins2(coins)));
}

【问题讨论】:

  • OP,您的帐户被黑客入侵了吗?看来您已经成为会员 5 年了,我想您知道 SO 的工作原理吗?
  • 提示:从冒泡排序算法开始,但实际上不对列表进行排序。而是将元素的总和放入哈希集中
  • 你“认为它有效”是什么意思?你有单元测试吗?
  • “寻找其他解决方案”不是一个很好的问题
  • 我会使用递归方法来生成组合,并使用TreeSet 来存储排序输出的结果。

标签: java algorithm


【解决方案1】:

正如您在问题陈述中提到的:

请使用加号输出所有可能数字的所有组合 仅限操作。

  • 解的时间复杂度将保持指数级,即 O(2N-1),因为我们必须尝试每个子序列数组。

  • 由于您使用的是 TreeSetadd 的复杂性会增加 log(n) 的开销,而 addAll() 会增加O(m log (n)) 的复杂性在最坏的情况下情况,其中mn 是每棵树中的元素数。看到这个answer

  • 从技术上讲,这将在每个步骤中增加 O(m log(n)) 复杂度,使其成为 O(2N - 1) * O(m log(n) )。

  • 我建议您最好使用 HashSet,其中 add()contains() 平均会给您 O(1) 的性能(如果有碰撞,但通常不是这样)。

  • 这样,复杂度仍然为 O(2N-1),最后有一个 additional(非乘法)排序开销(如果你 wish 让它排序) 这将是O(m log m) 其中m ~ 2N - 1. 您也可以比较两种方法的运行时间。

代码:

import java.util.*;
public class CoinCombination {
        public List<Integer> getCoinSums(int[] coins) {
        Set<Integer> set = new HashSet<>();
        List<Integer> sums = new ArrayList<>();
        for (int coin : coins) {
            int size = sums.size(); 
            for(int j=0;j<size;++j){
                int new_sum = sums.get(j) + coin;
                if(!set.contains(new_sum)){
                    sums.add(new_sum);   
                    set.add(new_sum);
                }
            }
            if(!set.contains(coin)){
                sums.add(coin);
                set.add(coin);
            }
        }

        Collections.sort(sums);
        return sums;
    }

    public static void main(String[] args) {
        CoinCombination combination = new CoinCombination();
        int[][] coins = {
            {10,20},
            {1,2,3},
            {10, 20, 20, 50},
            {10, 20, 20, 50, 100}
        };
        for(int[] each_set_of_coins : coins){
            System.out.println(combination.getCoinSums(each_set_of_coins).toString());
        }        
    }
}

输出:

[10, 20, 30]
[1, 2, 3, 4, 5, 6]
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]

【讨论】:

  • @sendon1982 很高兴为您提供帮助 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2015-10-07
  • 2018-06-29
  • 1970-01-01
  • 2018-07-04
相关资源
最近更新 更多