【发布时间】:2021-11-14 06:08:40
【问题描述】:
我有一个数字数组,比如说 [1,2,3,1,1000] ,现在我想获取这个数组的所有可能组合并计算它的总和。组合是有效的,使得两个组合具有不同的元素子集。然后将所有的和值按降序排列,得到前k个元素。
示例:
[1,2,3,1,1000]
组合:
删除较早的重复项,例如 (3,1) 匹配较早的 (1,3)。
(), (1), (2), (3), (1), (1000), (1,2), (1,3), (1,1) , (1,1000), (2,3), (2,1), (2,1000), (3,1), (3,1000) , (1,1000), (1,2,3), (1,2,1), (1,2,1000), (1,3,1), (1,3 ,1000), (1,1,1000), (2,3,1), (2,3,1000), (2,1,1000), (3,1,1000), (1,2,3,1), (1,2,3,1000), (1,2,1,1000), (1,3, 1,1000), (2,3,1,1000), (1,2,3,1,1000)
以及相应的总和:
0, 1, 2, 3, 1, 1000, 3, 4, 2, 1001, 5, 3, 1002, 4, 1003, 1001, 6, 4, 1003, 5, 1004, 1002, 6, 1005, 1003, 1004, 7, 1006, 1004, 1005, 1006, 1007
Getting top k=3, sums = 1007, 1006, 1005
So output is [1007, 1006, 1005].
约束:
- 数组大小 n = 1 到 105
- 数组元素 -109 到 109
- k 范围从 1 到 2000
这是我的代码,参考来自here:
static List<Long> printDistSum(int arr[]) {
List<Long> list = new ArrayList<>();
int n = arr.length;
// There are totoal 2^n subsets
long total = (long) Math.pow(2, n);
// Consider all numbers from 0 to 2^n - 1
for (int i = 0; i < total; i++) {
long sum = 0;
// Consider binary representation of
// current i to decide which elements
// to pick.
for (int j = 0; j < n; j++)
if ((i & (1 << j)) != 0)
sum += arr[j];
// Print sum of picked elements.
list.add(sum);
}
return list;
}
此代码适用于小范围的输入,但适用于大范围的输入。如何解决这个程序。
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。