Open In App

Find sum of difference of Indices with the same value for each Array element

Given an array arr[] of size N. The task is to find an array of size N such that the ith element is the summation of |i – j| for all j such that arr[i] is equal to arr[j].

Examples:



Input: arr = {2, 1, 4, 1, 2, 4, 4}
Output: {4, 2, 7, 2, 4, 4, 5}
Explanation:
=> Index 0: Another 2 is found at index 4. |0 – 4| = 4
=> Index 1: Another 1 is found at index 3. |1 – 3| = 2
=> Index 2: Two more 4s are found at indices 5 and 6. |2 – 5| + |2 – 6| = 7
=> Index 3: Another 1 is found at index 1. |3 – 1| = 2
=> Index 4: Another 2 is found at index 0. |4 – 0| = 4
=> Index 5: Two more 4s are found at indices 2 and 6. |5 – 2| + |5 – 6| = 4
=> Index 6: Two more 4s are found at indices 2 and 5. |6 – 2| + |6 – 5| = 5

Input: arr = {1, 10, 510, 10}
Output: {0 2 0 2}



A Naive Approach:

Iterate over the array and for each element run another loop for finding the similar elements, if similar elements found then keep sum of difference between their indices. 

Follow the steps below to implement the above idea:

Below is the implementation of the above approach:




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the resultant array
vector<long long> getDistances(vector<long long>& arr)
{
    int n = arr.size();
    vector<long long> result;
 
    // Run a loop for i = 0 to n - 1 (including)
    for (int i = 0; i < n; i++) {
 
        // Initialise a variable sum = 0;
        long long sum = 0;
 
        // Run another loop for j = 0 to n - 1 (including)
        for (int j = 0; j < n; j++) {
 
            // Check if arr[i] is equal to arr[j]
            if (arr[i] == arr[j]) {
 
                // Add the absolute difference of their
                // indices
                sum += abs(i - j);
            }
        }
 
        // Insert the sum into result.
        result.push_back(sum);
    }
 
    // Finally return result.
    return result;
}
 
// Driver code
int main()
{
    vector<long long> arr = { 2, 1, 4, 1, 2, 4, 4 };
 
    // Function call
    vector<long long> result = getDistances(arr);
 
    for (auto i : result) {
        cout << i << " ";
    }
 
    return 0;
}




// Java code to implement the approach
import java.io.*;
 
class GFG {
 
  // Function to find the resultant array
  static int[] getDistances(int[] arr)
  {
    int n = arr.length;
    int[] result = new int[n];
 
    // Run a loop for i = 0 to n - 1 (including)
    for (int i = 0; i < n; i++) {
 
      // Initialise a variable sum = 0;
      int sum = 0;
 
      // Run another loop for j = 0 to n - 1
      // (including)
      for (int j = 0; j < n; j++) {
 
        // Check if arr[i] is equal to arr[j]
        if (arr[i] == arr[j]) {
 
          // Add the absolute difference of their
          // indices
          sum += Math.abs(i - j);
        }
      }
 
      // Insert the sum into result.
      result[i] = sum;
    }
 
    // Finally return result.
    return result;
  }
 
  public static void main(String[] args)
  {
    int[] arr = { 2, 1, 4, 1, 2, 4, 4 };
 
    // Function call
    int[] result = getDistances(arr);
 
    for (int i = 0; i < result.length; i++) {
      System.out.print(result[i] + " ");
    }
  }
}
 
// This code is contributed by lokesh.




# Python code to implement the approach
 
# Function to find the resultant array
def getDistances(arr):
    n=len(arr)
    result=[]
     
    # Run a loop for i = 0 to n - 1 (including)
    for i in range(n):
        # Initialise a variable sum = 0
        sum=0
         
        # Run another loop for j = 0 to n - 1 (including)
        for j in range(n):
            # Check if arr[i] is equal to arr[j]
            if(arr[i]==arr[j]):
                # Add the absolute difference of their
                # indices
                sum+=abs(i-j)
                 
        # Insert the sum into result.
        result.append(sum)
     
    # Finally return result.
    return result
     
# Driver code
arr=[2, 1, 4, 1, 2, 4, 4]
 
#Function call
result=getDistances(arr)
 
for i in result:
    print(i,end=" ")
     
# This code is contributed by Pushpesh Raj




// C# code to implement the approach
using System;
 
public class GFG {
 
  // Function to find the resultant array
  static int[] getDistances(int[] arr)
  {
    int n = arr.Length;
    int[] result = new int[n];
 
    // Run a loop for i = 0 to n - 1 (including)
    for (int i = 0; i < n; i++) {
 
      // Initialise a variable sum = 0;
      int sum = 0;
 
      // Run another loop for j = 0 to n - 1
      // (including)
      for (int j = 0; j < n; j++) {
 
        // Check if arr[i] is equal to arr[j]
        if (arr[i] == arr[j]) {
 
          // Add the absolute difference of their
          // indices
          sum += Math.Abs(i - j);
        }
      }
 
      // Insert the sum into result.
      result[i] = sum;
    }
 
    // Finally return result.
    return result;
  }
 
  static public void Main()
  {
 
    // Code
    int[] arr = { 2, 1, 4, 1, 2, 4, 4 };
 
    // Function call
    int[] result = getDistances(arr);
 
    for (int i = 0; i < result.Length; i++) {
      Console.Write(result[i] + " ");
    }
  }
}
 
// This code is contributed by lokeshmvs21.




// JS code to implement the approach
 
// Function to find the resultant array
function getDistances(arr)
{
    let n = arr.length;
    let result = [];
 
    // Run a loop for i = 0 to n - 1 (including)
    for (let i = 0; i < n; i++) {
 
        // Initialise a variable sum = 0;
        let  sum = 0;
 
        // Run another loop for j = 0 to n - 1 (including)
        for (let j = 0; j < n; j++) {
 
            // Check if arr[i] is equal to arr[j]
            if (arr[i] == arr[j]) {
 
                // Add the absolute difference of their
                // indices
                sum += Math.abs(i - j);
            }
        }
 
        // Insert the sum into result.
        result.push(sum);
    }
 
    // Finally return result.
    return result;
}
 
// Driver code
let arr = [ 2, 1, 4, 1, 2, 4, 4 ];
 
// Function call
let result = getDistances(arr);
 
let ans = "";
for(let i = 0; i < result.length; i++)
    ans += result[i]+" ";
console.log(ans);
 
// This code is contributed by akashish__

Output
4 2 7 2 4 4 5 

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

An approach using Hashing:

Keep track of frequency and sum of the index of similar elements. Iterate over the array and calculate the sum of indices to the left of the current index which is similar to the current element. 

Similarly, calculate the sum of indices to the right of the current index which is similar to the current element. The result for the ith index would be the sum of all the differences. 

Illustration: 

Consider the arr = {1, 2, 1, 1, 2, 1}

Now, If have to calculate the result for the index i = 3 which is element 1.

  • To calculate the absolute value of the required result from the left would be something like => (i – 0) + (i – 2), which is equals to (2 * i – (0 + 2)). 
  • To generalise these, we can generate a formula to do the same: (frequency of similar element to the left* i) – (Sum of occurrences of such indices).
  • To calculate the absolute value of required result from the right would be something like => (5 – i)
    To generalise these, we can generate a formula to do the same: (Sum of occurrences of such indices) – (frequency of similar element to the right* i)
  • We can conclude from the above that: The result for the ith index would be:
    result[i] = ((leftFreq * i) – leftSum) + (rightSum – (rightFreq * i)).

Follow the steps below to implement the above idea:

Below is the implementation of the above approach:




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the resultant array
vector<long long> getDistances(vector<long long>& arr)
{
    int n = arr.size();
 
    // Declare a unordered map unmap for
    // storing the <key, <Total frequency,
    // total sum>> Declare a unordered map
    // unmap2 for storing the <key,
    // <frequency till any index i, sum
    // till ith index>>
    unordered_map<int, pair<long long, long long> > unmap,
        unmap2; // < key, <freq, sum>>
 
    // Iterate over the array and
    // update the unmap
    for (int i = 0; i < n; i++) {
        unmap[arr[i]] = { unmap[arr[i]].first + 1,
                          unmap[arr[i]].second + i };
    }
 
    // Declare an array result for
    // storing the result
    vector<long long> result(n);
 
    // Iterate over the given array
    for (int i = 0; i < n; i++) {
        auto curr = unmap2[arr[i]];
 
        long long leftSum = curr.second;
        long long leftFreq = curr.first;
 
        long long rightSum
            = unmap[arr[i]].second - leftSum - i;
        long long rightFreq
            = unmap[arr[i]].first - leftFreq - 1;
 
        // Update the result[i] with value mentioned
        result[i] = ((leftFreq * i) - leftSum)
                    + (rightSum - (rightFreq * i));
 
        // Update the unmap2 by increasing
        // the current elements frequency
        // and sum of all occurrence of
        // similar element till ith index.
        unmap2[arr[i]] = { unmap2[arr[i]].first + 1,
                           unmap2[arr[i]].second + i };
    }
 
    // Finally return result.
    return result;
}
 
// Driver code
int main()
{
    vector<long long> arr = {2, 1, 4, 1, 2, 4, 4 };
 
    // Function call
    vector<long long> result = getDistances(arr);
 
    for (auto i : result) {
        cout << i << " ";
    }
 
    return 0;
}




import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class GFG {
    public static void main(String[] args) {
        long[] arr = { 2, 1, 4, 1, 2, 4, 4 };
 
        List<Long> result = getDistances(arr);
 
        for (Long i : result) {
            System.out.print(i + " ");
        }
    }
 
    public static List<Long> getDistances(long[] arr) {
        int n = arr.length;
 
        Map<Long, Pair> unmap = new HashMap<>();
        Map<Long, Pair> unmap2 = new HashMap<>();
 
        for (int i = 0; i < n; i++) {
            Pair pair = unmap.get(arr[i]);
            if (pair == null) {
                unmap.put(arr[i], new Pair(1, i));
            } else {
                pair.freq++;
                pair.sum += i;
                unmap.put(arr[i], pair);
            }
        }
 
        List<Long> result = new ArrayList<>(n);
 
        for (int i = 0; i < n; i++) {
            Pair curr = unmap2.get(arr[i]);
 
            long leftSum = curr == null ? 0 : curr.sum;
            long leftFreq = curr == null ? 0 : curr.freq;
 
            Pair pair = unmap.get(arr[i]);
            long rightSum = pair.sum - leftSum - i;
            long rightFreq = pair.freq - leftFreq - 1;
 
            result.add((leftFreq * i) - leftSum + (rightSum - (rightFreq * i)));
 
            if (curr == null) {
                unmap2.put(arr[i], new Pair(1, i));
            } else {
                curr.freq++;
                curr.sum += i;
                unmap2.put(arr[i], curr);
            }
        }
 
        return result;
    }
}
 
class Pair {
    long freq;
    long sum;
 
    public Pair(long freq, long sum) {
        this.freq = freq;
        this.sum = sum;
    }
}
 
// This code is contributed by akashish__




# Function to find the resultant array
def getDistances(arr):
    n = len(arr)
 
    # Declare a unordered map unmap for
    # storing the <key, <Total frequency,
    # total sum>> Declare a unordered map
    # unmap2 for storing the <key,
    # <frequency till any index i, sum
    # till ith index>>
    unmap = {}
    unmap2 = {}
 
    # Iterate over the array and
    # update the unmap
    for i in range(n):
        if arr[i] in unmap:
            unmap[arr[i]] = (unmap[arr[i]][0] + 1, unmap[arr[i]][1] + i)
        else:
            unmap[arr[i]] = (1, i)
 
    # Declare an array result for
    # storing the result
    result = [0] * n
 
    # Iterate over the given array
    for i in range(n):
        if arr[i] in unmap2:
            curr = unmap2[arr[i]]
        else:
            curr = (0, 0)
 
        leftSum = curr[1]
        leftFreq = curr[0]
 
        if arr[i] in unmap:
            rightSum = unmap[arr[i]][1] - leftSum - i
            rightFreq = unmap[arr[i]][0] - leftFreq - 1
        else:
            rightSum = 0
            rightFreq = 0
 
        # Update the result[i] with value mentioned
        result[i] = (leftFreq * i) - leftSum + rightSum - (rightFreq * i)
 
        # Update the unmap2 by increasing
        # the current elements frequency
        # and sum of all occurrence of
        # similar element till ith index.
        if arr[i] in unmap2:
            unmap2[arr[i]] = (unmap2[arr[i]][0] + 1, unmap2[arr[i]][1] + i)
        else:
            unmap2[arr[i]] = (1, i)
 
    # Finally return result.
    return result
 
# Driver code
arr = [2, 1, 4, 1, 2, 4, 4]
 
# Function call
result = getDistances(arr)
 
for i in result:
  print(i, end=" ")
 
#This code is contributed by akashish__




using System;
using System.Collections.Generic;
using System.Linq;
 
public class GFG
{
   
  // Function to find the resultant array
  public static long[] GetDistances(long[] arr)
  {
    int n = arr.Length;
 
    // Declare a dictionary unmap for
    // storing the <key, <Total frequency,
    // total sum>> Declare a dictionary
    // unmap2 for storing the <key,
    // <frequency till any index i, sum
    // till ith index>>
    Dictionary<long, Tuple<long, long>> unmap = new Dictionary<long, Tuple<long, long>>(),
    unmap2 = new Dictionary<long, Tuple<long, long>>(); // < key, <freq, sum>>
 
    // Iterate over the array and
    // update the unmap
    for (int i = 0; i < n; i++)
    {
      if (unmap.ContainsKey(arr[i]))
      {
        unmap[arr[i]] = new Tuple<long, long>(unmap[arr[i]].Item1 + 1, unmap[arr[i]].Item2 + i);
      }
      else
      {
        unmap.Add(arr[i], new Tuple<long, long>(1, i));
      }
    }
 
    // Declare an array result for
    // storing the result
    long[] result = new long[n];
 
    // Iterate over the given array
    for (int i = 0; i < n; i++)
    {
      Tuple<long, long> curr = unmap2.ContainsKey(arr[i]) ? unmap2[arr[i]] : new Tuple<long, long>(0, 0);
 
      long leftSum = curr.Item2;
      long leftFreq = curr.Item1;
 
      long rightSum = unmap[arr[i]].Item2 - leftSum - i;
      long rightFreq = unmap[arr[i]].Item1 - leftFreq - 1;
 
      // Update the result[i] with value mentioned
      result[i] = (leftFreq * i) - leftSum + rightSum - (rightFreq * i);
 
      // Update the unmap2 by increasing
      // the current elements frequency
      // and sum of all occurrence of
      // similar element till ith index.
      if (unmap2.ContainsKey(arr[i]))
      {
        unmap2[arr[i]] = new Tuple<long, long>(unmap2[arr[i]].Item1 + 1, unmap2[arr[i]].Item2 + i);
      }
      else
      {
        unmap2.Add(arr[i], new Tuple<long, long>(1, i));
      }
    }
 
    // Finally return result.
    return result;
  }
 
  // Driver code
  static public void Main (){
    long[] arr = { 2, 1, 4, 1, 2, 4, 4 };
 
    // Function call
    long[] result = GetDistances(arr);
 
    foreach (long i in result)
    {
      Console.Write(i+" ");
    }
  }
}
 
// This code is contributed by akashish__




// JS code to implement the approach
 
// Function to find the resultant array
function getDistances( arr)
{
    let n = arr.length;
 
    // Declare a unordered map unmap for
    // storing the <key, <Total frequency,
    // total sum>> Declare a unordered map
    // unmap2 for storing the <key,
    // <frequency till any index i, sum
    // till ith index>>
 
    let unmap = {};
    let unmap2 = {}; // < key, <freq, sum>>
    for(let i=0;i<n;i++)
    {
        unmap[arr[i]] = {"first" : 0, "second" : 0};
        unmap2[arr[i]] = {"first" : 0, "second" : 0};
    }
 
    // Iterate over the array and
    // update the unmap
    for (let i = 0; i < n; i++) {
        unmap[arr[i]] = { "first" : unmap[arr[i]].first + 1,
                          "second" : unmap[arr[i]].second + i };
    }
 
    // Declare an array result for
    // storing the result
    let result = [];
    for(let i=0;i<n;i++)
    {
        result.push(0);
    }
 
    // Iterate over the given array
    for (let i = 0; i < n; i++) {
        let curr = unmap2[arr[i]];
 
        let  leftSum = curr.second;
        let  leftFreq = curr.first;
 
        let  rightSum
            = unmap[arr[i]].second - leftSum - i;
        let  rightFreq
            = unmap[arr[i]].first - leftFreq - 1;
 
        // Update the result[i] with value mentioned
        result[i] = ((leftFreq * i) - leftSum)
                    + (rightSum - (rightFreq * i));
 
        // Update the unmap2 by increasing
        // the current elements frequency
        // and sum of all occurrence of
        // similar element till ith index.
        unmap2[arr[i]] = {"first": unmap2[arr[i]].first + 1,
                           "second" : unmap2[arr[i]].second + i };
    }
 
    // Finally return result.
    return result;
}
 
// Driver code
let arr = [2, 1, 4, 1, 2, 4, 4 ];
 
// Function call
let result = getDistances(arr);
 
console.log(result);
// code by ksam24000

Output
4 2 7 2 4 4 5 

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

Related Articles:


Article Tags :