[英]Given a bunch of integer numbers, please output all combination of all possible numbers by using plus operation only
给定一堆整数,请仅使用加号操作输出所有可能数字的所有组合。
例如,
[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)));
}
正如您在问题陈述中提到的:
请仅通过加号输出所有可能数字的所有组合。
解决方案的时间复杂度将保持指数级,即O(2 N -1) ,因为我们必须尝试数组的每个子序列。
由于您使用一个TreeSet,在复杂add
将增加数(n)和中的addAll(的开销)将增加的复杂度O(m log (n))
在最坏的情况下,其中m
和n
是数量每棵树中的元素。 看到这个答案 。
从技术上讲,这将在每一步中增加O(m log(n))的复杂度,使其成为O(2 N -1)* O(m log(n))。
我建议您最好使用HashSet ,其中add()
和contains()
会平均给您O(1)的性能(如果发生冲突,可能会提高到O(n),但通常不是这种情况)。
这样,复杂度保持为O(2 N -1),最后additional
了排序的additional
(非乘法)开销(如果您wish
对其进行排序),将是O(m log m)
,其中m
N -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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.