📜  n个整数数组中所有对上的f(a [i],a [j])的总和

📅  最后修改于: 2021-04-27 19:37:12             🧑  作者: Mango

给定n个整数的数组,找到所有对(i,j)的f(a [i],a [j])之和,以使(1 <= i f(a [i],a [j]):

If |a[j]-a[i]| > 1
   f(a[i], a[j]) = a[j] - a[i] 
Else // if |a[j]-a[i]| <= 1
   f(a[i], a[j]) = 0

例子:

Input : 6 6 4 4 
Output : -8 
Explanation: 
All pairs are: (6 - 6) + (6 - 6) +
(6 - 6) + (4 - 6) + (4 - 6) + (4 - 6) + 
(4 - 6) + (4 - 4) + (4 - 4) = -8

Input: 1 2 3 1 3
Output: 4 
Explanation: the pairs that add up are:
(3, 1), (3, 1) to give 4, rest all pairs 
according to condition gives 0. 

天真的方法是遍历所有对,并计算f(a [i],a [j])并在两个嵌套循环中遍历时求和,这将为我们提供答案。
时间复杂度: O(n ^ 2)

一种有效的方法是使用映射/哈希函数对每个出现的数字进行计数,然后遍历列表。在遍历列表时,我们将其前面的数字与数字本身相乘。然后,将该结果与该数字之前的数字的总和相减,以获得该数字可能存在的所有对的差之和。要删除绝对差小于= 1的所有对,只需从先前计算的总和中减去(number-1)和(number + 1)的出现次数。在这里,我们从计算出的总和中减去(number-1)的计数,因为先前已将其添加到总和中,并且由于将负数已添加到所有对的预计算总和中,因此我们添加了(number + 1)计数。

时间复杂度: O(n)

下面是上述方法的实现:

C++
// CPP program to calculate the 
// sum of f(a[i], aj])
#include 
using namespace std;
  
// Function to calculate the sum
int sum(int a[], int n)
{
    // map to keep a count of occurrences
    unordered_map cnt;
  
    // Traverse in the list from start to end
    // number of times a[i] can be in a pair and
    // to get the difference we subtract pre_sum.
    int ans = 0, pre_sum = 0;
    for (int i = 0; i < n; i++) {
        ans += (i * a[i]) - pre_sum;
        pre_sum += a[i];
  
        // if the (a[i]-1) is present then
        // subtract that value as f(a[i], a[i]-1)=0
        if (cnt[a[i] - 1])
            ans -= cnt[a[i] - 1];
  
        // if the (a[i]+1) is present then
        // add that value as f(a[i], a[i]-1)=0
        // here we add as a[i]-(a[i]-1)<0 which would 
        // have been added as negative sum, so we add  
        // to remove this pair from the sum value
        if (cnt[a[i] + 1])
            ans += cnt[a[i] + 1];
  
        // keeping a counter for every element
        cnt[a[i]]++;
    }
    return ans;
}
  
// Driver code
int main()
{
    int a[] = { 1, 2, 3, 1, 3 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << sum(a, n);
    return 0;
}


Java
// Java program to calculate  
// the sum of f(a[i], aj])
import java.util.*; 
public class GfG {
  
    // Function to calculate the sum
    public static int sum(int a[], int n)
    {
        // Map to keep a count of occurrences
        Map cnt = new HashMap(); 
          
        // Traverse in the list from start to end
        // number of times a[i] can be in a pair and
        // to get the difference we subtract pre_sum
        int ans = 0, pre_sum = 0;
        for (int i = 0; i < n; i++) {
            ans += (i * a[i]) - pre_sum;
            pre_sum += a[i];
      
            // If the (a[i]-1) is present then subtract
            // that value as f(a[i], a[i]-1) = 0
            if (cnt.containsKey(a[i] - 1))
                ans -= cnt.get(a[i] - 1);
  
            // If the (a[i]+1) is present then
            // add that value as f(a[i], a[i]-1)=0
            // here we add as a[i]-(a[i]-1)<0 which would 
            // have been added as negative sum, so we add 
            // to remove this pair from the sum value
            if (cnt.containsKey(a[i] + 1))
                ans += cnt.get(a[i] + 1);
  
            // keeping a counter for every element
            if(cnt.containsKey(a[i])) {
                cnt.put(a[i], cnt.get(a[i]) + 1);
            }
            else {
                cnt.put(a[i], 1);
            }
        }
        return ans;
    }
  
    // Driver code
    public static void main(String args[])
    {
        int a[] = { 1, 2, 3, 1, 3 };
        int n = a.length;
        System.out.println(sum(a, n));
    }
}
  
// This code is contributed by Swetank Modi


Python3
# Python3 program to calculate the 
# sum of f(a[i], aj])
  
# Function to calculate the sum 
def sum(a, n): 
  
    # map to keep a count of occurrences 
    cnt = dict()
  
    # Traverse in the list from start to end 
    # number of times a[i] can be in a pair and 
    # to get the difference we subtract pre_sum. 
    ans = 0
    pre_sum = 0
    for i in range(n): 
        ans += (i * a[i]) - pre_sum 
        pre_sum += a[i] 
  
        # if the (a[i]-1) is present then 
        # subtract that value as f(a[i], a[i]-1)=0 
        if (a[i] - 1) in cnt:
            ans -= cnt[a[i] - 1] 
  
        # if the (a[i]+1) is present then add that  
        # value as f(a[i], a[i]-1)=0 here we add 
        # as a[i]-(a[i]-1)<0 which would have been 
        # added as negative sum, so we add to remove  
        # this pair from the sum value 
        if (a[i] + 1) in cnt:
            ans += cnt[a[i] + 1] 
  
        # keeping a counter for every element 
        if a[i] not in cnt:
            cnt[a[i]] = 0
        cnt[a[i]] += 1
      
    return ans 
  
# Driver Code 
if __name__ == '__main__':
    a = [1, 2, 3, 1, 3]
    n = len(a)
    print(sum(a, n))
          
# This code is contributed by
# SHUBHAMSINGH10


C#
using System;
using System.Collections.Generic;
  
// C#  program to calculate   
// the sum of f(a[i], aj]) 
public class GfG
{
  
    // Function to calculate the sum 
    public static int sum(int[] a, int n)
    {
        // Map to keep a count of occurrences 
        IDictionary cnt = new Dictionary();
  
        // Traverse in the list from start to end 
        // number of times a[i] can be in a pair and 
        // to get the difference we subtract pre_sum 
        int ans = 0, pre_sum = 0;
        for (int i = 0; i < n; i++)
        {
            ans += (i * a[i]) - pre_sum;
            pre_sum += a[i];
  
            // If the (a[i]-1) is present then subtract 
            // that value as f(a[i], a[i]-1) = 0 
            if (cnt.ContainsKey(a[i] - 1))
            {
                ans -= cnt[a[i] - 1];
            }
  
            // If the (a[i]+1) is present then 
            // add that value as f(a[i], a[i]-1)=0 
            // here we add as a[i]-(a[i]-1)<0 which would  
            // have been added as negative sum, so we add  
            // to remove this pair from the sum value 
            if (cnt.ContainsKey(a[i] + 1))
            {
                ans += cnt[a[i] + 1];
            }
  
            // keeping a counter for every element 
            if (cnt.ContainsKey(a[i]))
            {
                cnt[a[i]] = cnt[a[i]] + 1;
            }
            else
            {
                cnt[a[i]] = 1;
            }
        }
        return ans;
    }
  
    // Driver code 
    public static void Main(string[] args)
    {
        int[] a = new int[] {1, 2, 3, 1, 3};
        int n = a.Length;
        Console.WriteLine(sum(a, n));
    }
}
  
// This code is contributed by Shrikant13


输出 :

4