您可以使用位操作,而不是使用递归来生成所有可能的子集。对于给出 4 个项目的示例,有 2^4 个可能的子集。因此,您可以使用 4 位二进制数来表示这 2^4 个子集。二进制数将从 0 计数到 2^4-1=15。对于每个数字,您检查 4 位的状态。如果设置了该位,则该元素包含在该子集中,否则不包含。
您可以以Working Java Program 的形式轻松实现此逻辑。
int[] arr = {4 , 7 , 2 , 5};
double ans = 0;
int numCombinations = (int)Math.pow(2, arr.length);
// Iterate over all the subsets represented in the form of binary numbers
for(int i=0; i<numCombinations; i++){
int sum = 0;
// check whether a bit is set or not. If the bit is set, then that
// number is present in that subset, else it is not present.
for(int bit=0; bit<arr.length; bit++){
if( (i & (1<<bit)) != 0){
sum += arr[bit];
}
}
ans += (double)sum;
}
//Divide by numCombinations-1 as we are not considering the empty subset{}
System.out.println(ans/(numCombinations-1));
对于给定的情况,这个程序正确地计算出答案为 9.6。
运行时间O(n.2^n)
编辑:更好的解决方案
假设您正在生成 n 个元素的所有子集。现在元素有两种可能。它要么被包含,要么不被包含。因此,假设您拥有所有 n-1 个元素子集。对于所有这些 n-1 个元素子集,您将执行上述两种情况之一,即。您将包含或不包含第 n 个元素。因此,我们可以说如果我们总共有 M 个子集,那么任何元素都会出现 M/2 次strong>。
在给定的情况下,M 是 2^n,因为我们正在生成所有子集。所以任何元素都会出现 2^(n-1) 次。
所以所有子集中所有数字的总和将是
所有子集的个数之和 = arr[0] * 2^(n-1) + arr1 * 2^(n-1) + .......arr[n] * 2^ (n-1)
将其除以子集的数量将给出答案。
子集总数 = 2^n - 1。
我们减去 1,因为我们不考虑空子集 {}。
所以对于给定的情况,答案将变为
(4+7+2+5) * 2^(n-1) / (2^n - 1) = 9.6
运行时间:O(n)