Skip to content
Related Articles

Related Articles

Sum of absolute differences of indices of occurrences of each array element | Set 2
  • Difficulty Level : Medium
  • Last Updated : 23 Apr, 2021

 Given an array, arr[] consisting of N integers, the task for each array element arr[i] is to print the sum of |i – j| for all possible indices j such that arr[i] = arr[j].

Examples:

Input: arr[] = {1, 3, 1, 1, 2}
Output: 5 0 3 4 0
Explanation:
For arr[0], sum = |0 – 0| + |0 – 2| + |0 – 3| = 5.
For arr[1], sum = |1 – 1| = 0.
For arr[2], sum = |2 – 0| + |2 – 2| + |2 – 3| = 3.
For arr[3], sum = |3 – 0| + |3 – 2| + |3 – 3| = 4.
For arr[4], sum = |4 – 4| = 0.
Therefore, the required output is 5 0 3 4 0.

Input: arr[] = {1, 1, 1}
Output: 3 2 3

Naive Approach: Please refer to the previous post of this article for the simplest approach to solve the problem. 
Time Complexity: O(N2)
Auxiliary Space: O(N)

Map-based Approach: Please refer to the previous post of this article to solve the problem using Map
Time Complexity: O(N*L)
Auxiliary Space: O(N)

Efficient Approach: The above approach can also be optimized by storing the previous index and the count of occurrences of every element in a HashMap. Follow the steps below to solve the problem:

  • Initialize a HashMap, say M to store arr[i] as key and (count, previous index) as value.
  • Initialize two arrays L[] and R[] of size N where L[i] denotes the sum of |i – j| for all possible indices j < i and arr[i] = arr[j] and R[i] denotes the sum of |i – j| for all possible indices j > i and arr[i] = arr[j].
  • Traverse the given array arr[] over the range [0, N – 1] and perform the following steps:
    • If arr[i] is present in the map M, then update the value of L[i] to 0 and M[arr[i]] to store pair {1, i} where the first element denotes the count of occurrences and the second element denotes the previous index of the element.
    • Otherwise, find the value of arr[i] from the map M, and store the count and previous index in variables cnt and j respectively.
    • Update the value of L[i] to (cnt * (i – j) + L[j]) and the value of arr[i] in M to store pair (cnt + 1, i).
  • Repeat the same process to update the values in the array R[].
  • Iterate over the range [0, N – 1] using the variable i and print the value (L[i] + R[i]) as the result.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Stores the count of occurrences
// and previous index of every element
struct pairr
{
    int count, prevIndex;
     
    // Constructor
    pairr(int countt, int prevIndexx)
    {
        count = countt;
        prevIndex = prevIndexx;
    }
};
 
// Function to calculate the sum of
// absolute differences of indices
// of occurrences of array element
void findSum(int arr[], int n)
{
     
    // Stores the count of elements
    // and their previous indices
    map<int, pairr*> mapp;
 
    // Initialize 2 arrays left[]
    // and right[] of size N
    int left[n];
    int right[n];
 
    // Traverse the given array
    for(int i = 0; i < n; i++)
    {
         
        // If arr[i] is present in the Map
        if (mapp.find(arr[i]) == mapp.end())
        {
             
            // Update left[i] to 0
            // and update the value
            // of arr[i] in map
            left[i] = 0;
            mapp[arr[i]] = new pairr(1, i);
        }
         
        // Otherwise, get the value from
        // the map and update left[i]
        else
        {
            pairr* tmp = mapp[arr[i]];
            left[i] = (tmp->count) * (i - tmp->prevIndex) +
                   left[tmp->prevIndex];
            mapp[arr[i]] = new pairr(tmp->count + 1, i);
        }
    }
 
    // Clear the map to calculate right[] array
    mapp.clear();
 
    // Traverse the array arr[] in reverse
    for(int i = n - 1; i >= 0; i--)
    {
         
        // If arr[i] is present in theMap
        if (mapp.find(arr[i]) == mapp.end())
        {
             
            // Update right[i] to 0
            // and update the value
            // of arr[i] in the Map
            right[i] = 0;
            mapp[arr[i]] = new pairr(1, i);
        }
 
        // Otherwise get the value from
        // the map and update right[i]
        else
        {
            pairr* tmp = mapp[arr[i]];
            right[i] = (tmp->count) *
                       (abs(i - tmp->prevIndex)) +
                          right[tmp->prevIndex];
 
            mapp[arr[i]] = new pairr(tmp->count + 1, i);
        }
    }
 
    // Iterate in the range [0, N-1]
    // and print the sum of left[i]
    // and right[i] as the result
    for(int i = 0; i < n; i++)
        cout << left[i] + right[i] << " ";
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 3, 1, 1, 2 };
    int N = 5;
     
    findSum(arr, N);
}
 
// This code is contributed by mohit kumar 29

Java




// Java program for the above approach
 
import java.util.*;
 
class GFG {
 
    // Stores the count of occurrences
    // and previous index of every element
    static class pair {
        int count, prevIndex;
 
        // Constructor
        pair(int count, int prevIndex)
        {
            this.count = count;
            this.prevIndex = prevIndex;
        }
    }
 
    // Function to calculate the sum of
    // absolute differences of indices
    // of occurrences of array element
    static void findSum(int[] arr, int n)
    {
        // Stores the count of elements
        // and their previous indices
        Map<Integer, pair> map = new HashMap<>();
 
        // Initialize 2 arrays left[]
        // and right[] of size N
        int[] left = new int[n];
        int[] right = new int[n];
 
        // Traverse the given array
        for (int i = 0; i < n; i++) {
 
            // If arr[i] is present in the Map
            if (!map.containsKey(arr[i])) {
 
                // Update left[i] to 0
                // and update the value
                // of arr[i] in map
                left[i] = 0;
                map.put(arr[i], new pair(1, i));
            }
 
            // Otherwise, get the value from
            // the map and update left[i]
            else {
                pair tmp = map.get(arr[i]);
                left[i] = (tmp.count)
                              * (i - tmp.prevIndex)
                          + left[tmp.prevIndex];
                map.put(
                    arr[i], new pair(
                                tmp.count + 1, i));
            }
        }
 
        // Clear the map to calculate right[] array
        map.clear();
 
        // Traverse the array arr[] in reverse
        for (int i = n - 1; i >= 0; i--) {
 
            // If arr[i] is present in theMap
            if (!map.containsKey(arr[i])) {
 
                // Update right[i] to 0
                // and update the value
                // of arr[i] in the Map
                right[i] = 0;
                map.put(arr[i], new pair(1, i));
            }
 
            // Otherwise get the value from
            // the map and update right[i]
            else {
 
                pair tmp = map.get(arr[i]);
                right[i]
                    = (tmp.count)
                          * (Math.abs(i - tmp.prevIndex))
                      + right[tmp.prevIndex];
 
                map.put(
                    arr[i], new pair(
                                tmp.count + 1, i));
            }
        }
 
        // Iterate in the range [0, N-1]
        // and print the sum of left[i]
        // and right[i] as the result
        for (int i = 0; i < n; i++)
            System.out.print(
                left[i] + right[i] + " ");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 1, 3, 1, 1, 2 };
        int N = arr.length;
        findSum(arr, N);
    }
}
Output: 
5 0 3 4 0

 

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.




My Personal Notes arrow_drop_up
Recommended Articles
Page :