子集差异之和
给定一个由 n 个数字组成的集合 S,求每个子集的最后一个元素和第一个元素之间的差之和。我们通过保持它们在输入集 S 中出现的相同顺序来找到每个子集的第一个和最后一个元素。
即 sumSetDiff(S) = ∑ (last(s) – first(s)),
其中 sum 遍历 S 的所有子集 s。
注意:子集中的元素应与集合 S 中的元素顺序相同。
例子:
S = {5, 2, 9, 6}, n = 4
Subsets are:
{5}, last(s)-first(s) = 0.
{2}, last(s)-first(s) = 0.
{9}, last(s)-first(s) = 0.
{6}, last(s)-first(s) = 0.
{5,2}, last(s)-first(s) = -3.
{5,9}, last(s)-first(s) = 4.
{5,6}, last(s)-first(s) = 1.
{2,9}, last(s)-first(s) = 7.
{2,6}, last(s)-first(s) = 4.
{9,6}, last(s)-first(s) = -3.
{5,2,9}, last(s)-first(s) = 4.
{5,2,6}, last(s)-first(s) = 1.
{5,9,6}, last(s)-first(s) = 1.
{2,9,6}, last(s)-first(s) = 4.
{5,2,9,6}, last(s)-first(s) = 1.
Output = -3+4+1+7+4-3+4+1+1+4+1
= 21.
这个问题的一个简单解决方案是找到集合 S 的每个子集 s 的最后一个元素和第一个元素之间的差异,并输出所有这些差异的总和。这种方法的时间复杂度是 O(2 n )。
解决线性时间复杂度问题的有效解决方案。
给定一个由 n 个数字组成的集合 S,我们需要计算 S 的每个子集的最后一个元素和第一个元素之间的差之和,即
sumSetDiff(S) = ∑ (last(s) – first(s)),其中 sum 遍历 S 的所有子集 s。
等效地,
sumSetDiff(S) = ∑ (last(s)) – ∑ (first(s)),
换句话说,我们可以分别计算每个子集的最后一个元素的和,以及每个子集的第一个元素的和,然后计算它们的差。
假设 S 的元素是 {a1, a2, a3,…, an}。注意以下观察:
- 包含元素a1作为第一个元素的子集可以通过取 {a2, a3,…, an} 的任何子集然后将 a1 包含在其中来获得。这种子集的数量将是 2 n-1 。
- 包含元素 a2 作为第一个元素的子集可以通过取 {a3, a4,…, an} 的任何子集然后将 a2 包含在其中来获得。这种子集的数量将是 2 n-2 。
- 包含元素 ai 作为第一个元素的子集可以通过取 {ai, a(i+1),…, an} 的任何子集然后将 ai 包含在其中来获得。这种子集的数量将是 2 ni 。
因此,所有子集的第一个元素的总和将是:
SumF = a1.2 n-1 + a2.2 n-2 +…+ an.1以类似的方式,我们可以计算 S 的所有子集的最后一个元素的总和(在每一步中将 ai 作为最后一个元素而不是第一个元素,然后获得所有子集)。
SumL = a1.1 + a2.2 +…+ an.2 n-1最后,我们问题的答案将是SumL – SumF 。
执行:
C++
// A C++ program to find sum of difference between // last and first element of each subset #include
// Returns the sum of first elements of all subsets int SumF(int S[], int n) { int sum = 0; // Compute the SumF as given in the above explanation for (int i = 0; i < n; i++) sum = sum + (S[i] * pow(2, n-i-1)); return sum; } // Returns the sum of last elements of all subsets int SumL(int S[], int n) { int sum = 0; // Compute the SumL as given in the above explanation for (int i = 0; i < n; i++) sum = sum + (S[i] * pow(2, i)); return sum; } // Returns the difference between sum of last elements of // each subset and the sum of first elements of each subset int sumSetDiff(int S[], int n) { return SumL(S, n) - SumF(S, n); } // Driver program to test above function int main() { int n = 4; int S[] = {5, 2, 9, 6}; printf("%d\n", sumSetDiff(S, n)); return 0; } Java
// A Java program to find sum of difference // between last and first element of each // subset class GFG { // Returns the sum of first elements // of all subsets static int SumF(int S[], int n) { int sum = 0; // Compute the SumF as given in // the above explanation for (int i = 0; i < n; i++) sum = sum + (int)(S[i] * Math.pow(2, n - i - 1)); return sum; } // Returns the sum of last elements // of all subsets static int SumL(int S[], int n) { int sum = 0; // Compute the SumL as given in // the above explanation for (int i = 0; i < n; i++) sum = sum + (int)(S[i] * Math.pow(2, i)); return sum; } // Returns the difference between sum // of last elements of each subset and // the sum of first elements of each // subset static int sumSetDiff(int S[], int n) { return SumL(S, n) - SumF(S, n); } // Driver program public static void main(String arg[]) { int n = 4; int S[] = { 5, 2, 9, 6 }; System.out.println(sumSetDiff(S, n)); } } // This code is contributed by Anant Agarwal.
Python3
# Python3 program to find sum of # difference between last and # first element of each subset # Returns the sum of first # elements of all subsets def SumF(S, n): sum = 0 # Compute the SumF as given # in the above explanation for i in range(n): sum = sum + (S[i] * pow(2, n - i - 1)) return sum # Returns the sum of last # elements of all subsets def SumL(S, n): sum = 0 # Compute the SumL as given # in the above explanation for i in range(n): sum = sum + (S[i] * pow(2, i)) return sum # Returns the difference between sum # of last elements of each subset and # the sum of first elements of each subset def sumSetDiff(S, n): return SumL(S, n) - SumF(S, n) # Driver program n = 4 S = [5, 2, 9, 6] print(sumSetDiff(S, n)) # This code is contributed by Anant Agarwal.
C#
// A C# program to find sum of difference // between last and first element of each // subset using System; class GFG { // Returns the sum of first elements // of all subsets static int SumF(int []S, int n) { int sum = 0; // Compute the SumF as given in // the above explanation for (int i = 0; i < n; i++) sum = sum + (int)(S[i] * Math.Pow(2, n - i - 1)); return sum; } // Returns the sum of last elements // of all subsets static int SumL(int []S, int n) { int sum = 0; // Compute the SumL as given in // the above explanation for (int i = 0; i < n; i++) sum = sum + (int)(S[i] * Math.Pow(2, i)); return sum; } // Returns the difference between sum // of last elements of each subset and // the sum of first elements of each // subset static int sumSetDiff(int []S, int n) { return SumL(S, n) - SumF(S, n); } // Driver program public static void Main() { int n = 4; int []S = { 5, 2, 9, 6 }; Console.Write(sumSetDiff(S, n)); } } // This code is contributed by nitin mittal.
PHP
输出:21
时间复杂度:O(n)