📜  子集差异之和

📅  最后修改于: 2022-05-13 01:57:50.953000             🧑  作者: Mango

子集差异之和

给定一个由 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}。注意以下观察:

  1. 包含元素a1作为第一个元素的子集可以通过取 {a2, a3,…, an} 的任何子集然后将 a1 包含在其中来获得。这种子集的数量将是 2 n-1
  2. 包含元素 a2 作为第一个元素的子集可以通过取 {a3, a4,…, an} 的任何子集然后将 a2 包含在其中来获得。这种子集的数量将是 2 n-2
  3. 包含元素 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)