Sum of f(a[i], a[j]) over all pairs in an array of n integers - GeeksforGeeks

29 May, 2021
Given an array of n integers, find the sum of f(a[i], a[j]) of all pairs (i, j) such that (1 <= i < j <= n).  
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
Examples: 
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.  
A naive approach is to iterate through all pairs and calculate f(a[i], a[j]), and summing it up while traversing two nested loops will give us our answer. Time Complexity: O(n^2)  
An efficient approach would be to use a map/hash function to keep a count of every occurring number and then traverse through the list. While traversing through the list, we multiply the count of numbers that are before it and the number itself. Then subtract this result with the pre-sum of the number before that number to get the sum of the difference of all pairs possible with that number. To remove all pairs whose absolute difference is <=1, simply subtract the count of occurrence of (number-1) and (number+1) from the previously computed sum. Here we subtract the count of (number-1) from the computed sum as it had been previously added to the sum, and we add the (number+1) count since the negative has been added to the pre-computed sum of all pairs.Time Complexity: O(n) 
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// CPP program to calculate the// sum of f(a[i], aj])#include <bits/stdc++.h>using namespace std; // Function to calculate the sumint sum(int a[], int n){    // map to keep a count of occurrences    unordered_map<int, int> 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 codeint main(){    int a[] = { 1, 2, 3, 1, 3 };    int n = sizeof(a) / sizeof(a[0]);    cout << sum(a, n);    return 0;}
// 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<Integer,Integer> cnt = new HashMap<Integer,Integer>();                 // 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 program to calculate the# sum of f(a[i], aj]) # Function to calculate the sumdef 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 Codeif __name__ == '__main__':    a = [1, 2, 3, 1, 3]    n = len(a)    print(sum(a, n))         # This code is contributed by# SHUBHAMSINGH10
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<int, int> cnt = new Dictionary<int, int>();         // 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
<script> // Javascript program to calculate the// sum of f(a[i], aj]) // Function to calculate the sumfunction sum(a, n){    // map to keep a count of occurrences    var cnt = new Map();     // 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.    var ans = 0, pre_sum = 0;    for (var 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.has(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.has(a[i] + 1))            ans += cnt.get(a[i] + 1);         // keeping a counter for every element        if(cnt.has(a[i]))            cnt.set(a[i], cnt.get(a[i])+1)        else            cnt.set(a[i], 1)    }    return ans;} // Driver codevar a = [1, 2, 3, 1, 3];var n = a.length;document.write( sum(a, n));  </script>
Output:  
4
 
shrikanth13
SHUBHAMSINGH10
famously
cpp-unordered_map
Arrays
Competitive Programming
Hash
Mathematical
Arrays
Hash
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Top 50 Array Coding Problems for Interviews
Stack Data Structure (Introduction and Program)
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
Competitive Programming - A Complete Guide
Practice for cracking any coding interview
Arrow operator -> in C/C++ with Examples
Prefix Sum Array - Implementation and Applications in Competitive Programming
Fast I/O for Competitive Programming