Open In App
Related Articles

Sum of all distances between occurrences of same characters in a given string

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

Given a string S, the task is to find the sum of distances between all pairs of indices from the given string which contains the same character.

Examples:

Input: S = “ababa”
Output: 10
Explanation:
The pair of indices having same character are: (0, 2) (0, 4) (1, 3) (2, 4)
Sum of absolute differences between these pair of indices = |2 – 0| + |4 – 0| + |1 – 3| + |2 – 4| = 10. 
Therefore, the required answer is 10.

Input: S = “ttt”
Output: 4

Naive Approach: The simplest approach to solve the problem is to traverse the string and for each character encountered, traverse the remaining string on its right to find occurrences of that character. For every repetition of characters found, keep adding the absolute difference between the concerned indices to the answer. Finally, print the sum obtained. 

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

Below is the implementation of the above approach:

C++

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a string
int findSum(string s)
{
    int sum = 0;
    for (int i = 0; i < s.size(); i++) {
        for (int j = i + 1; j < s.size(); j++) {
 
            // If similar characters are found
            if (s[i] == s[j]) {
 
                // Add the difference
                // of their positions
                sum += (j - i);
            }
        }
    }
 
    // Return the answer
    return sum;
}
 
// Driver Code
int main()
{
    string s = "ttt";
    cout << findSum(s) << endl;
}

                    

Java

// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a String
static int findSum(String s)
{
    int sum = 0;
    for (int i = 0; i < s.length(); i++)
    {
        for (int j = i + 1; j < s.length(); j++)
        {
            // If similar characters are found
            if (s.charAt(i) == s.charAt(j))
            {
                // Add the difference
                // of their positions
                sum += (j - i);
            }
        }
    }
 
    // Return the answer
    return sum;
}
 
// Driver Code
public static void main(String[] args)
{
    String s = "ttt";
    System.out.print(findSum(s) + "\n");
}
}
// This code is contributed by shikhasingrajput

                    

Python3

# Python3 program for the above approach
  
# Function to calculate the sum
# of distances between occurrences
# of same characters in a string
def findSum(s):
     
    sum = 0
    for i in range(len(s)):
        for j in range(i + 1, len(s)):
  
            # If similar characters are found
            if (s[i] == s[j]):
  
                # Add the difference
                # of their positions
                sum += (j - i)
  
    # Return the answer
    return sum
 
# Driver Code
s = "ttt"
 
print(findSum(s))
 
# This code is contributed by code_hunt

                    

C#

// C# program for
// the above approach
using System;
class GFG{
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a String
static int findSum(String s)
{
  int sum = 0;
  for (int i = 0; i < s.Length; i++)
  {
    for (int j = i + 1; j < s.Length; j++)
    {
      // If similar characters
      // are found
      if (s[i] == s[j])
      {
        // Add the difference
        // of their positions
        sum += (j - i);
      }
    }
  }
 
  // Return the answer
  return sum;
}
 
// Driver Code
public static void Main(String[] args)
{
  String s = "ttt";
  Console.Write(findSum(s) + "\n");
}
}
  
// This code is contributed by shikhasingrajput

                    

Javascript

<script>
// javascript program for the
// above approach
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a String
function findSum(s)
{
    let sum = 0;
    for (let i = 0; i < s.length; i++)
    {
        for (let j = i + 1; j < s.length; j++)
        {
            // If similar characters are found
            if (s[i] == s[j])
            {
                // Add the difference
                // of their positions
                sum += (j - i);
            }
        }
    }
  
    // Return the answer
    return sum;
}
  
// Driver Code
 
     let s = "ttt";
    document.write(findSum(s) + "<br/>");
 
// This code is contributed by target_2.
</script>

                    

Output
4






Efficient Approach: The above approach can be optimized based on the following observations:

  • Initially for every character, assume that all its similar characters are at index 0.
  • With the above assumption, the required sum becomes equal to:

Number of previously visited similar characters * Index of the character – sum of distances of those similar characters from index 0

Therefore, follow the steps below to solve the problem:

  • Initialize two arrays visited[] and distance[] to store the frequency of each character present in the string and the distance between the previous occurrences of each character respectively.
  • Traverse the string and for every character encountered, i.e. S[i], update the following:
    • Add visited[S[i] * i – distance[S[i]] to the required sum.
    • Increment visited[S[i]] to increase frequency of characters.
    • Increase distance[S[i]] by i, to increase the distance from the previous occurrence of S[i], considered to be 0.
  • Once the above steps are completed, print the sum obtained.

Below is the implementation of the above approach :

C++

#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a string
int findSum(string s)
{
    // Initially make all the distances
    // and number of characters visited as 0
   
    vector<int> visited(256, 0);
    vector<int> distance(256, 0);
    
    int sum = 0;
  
    for(int i = 0; i < s.length(); i++)
    {
          
        // Assuming that all the similar
        // characters are located at index 0
  
        // Add visited[s[i]]*i to sum
        // and subtract the distances of
        // characters from index 0
        sum += visited[s[i] - 'a'] * i -
              distance[s[i] - 'a'];
  
        // Increment the number of
        // visited characters
        visited[s[i] - 'a']++;
  
        // Add the distance of the
        // character from position 0
        // i.e., (i - 0) = i
        distance[s[i] - 'a'] += i;
    }
  
    // Return the answer
    return sum;
}
 
int main() {
     
    
    string s = "ttt";
    cout << findSum(s) << "\n";
    return 0;
}

                    

Java

// Java program for the above approach
import java.io.*;
 
class GFG{
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a string
static int findSum(String s)
{
    int[] visited = new int[256];
    int[] distance = new int[256];
 
    // Initially make all the distances
    // and number of characters visited as 0
    for(int i = 0; i < 256; i++)
    {
        visited[i] = 0;
        distance[i] = 0;
    }
 
    int sum = 0;
 
    for(int i = 0; i < s.length(); i++)
    {
         
        // Assuming that all the similar
        // characters are located at index 0
 
        // Add visited[s[i]]*i to sum
        // and subtract the distances of
        // characters from index 0
        sum += visited[s.charAt(i)] * i -
              distance[s.charAt(i)];
 
        // Increment the number of
        // visited characters
        visited[s.charAt(i)]++;
 
        // Add the distance of the
        // character from position 0
        // i.e., (i - 0) = i
        distance[s.charAt(i)] += i;
    }
 
    // Return the answer
    return sum;
}
 
// Driver code
public static void main (String[] args)
{
    String s = "ttt";
     
    // Function call
    System.out.println(findSum(s));
}
}
 
// This code is contributed by offbeat

                    

Python3

# Python3 program for the above approach
 
# Function to calculate the sum
# of distances between occurrences
# of same characters in a string
def findSum(s):
    visited = [0 for i in range(256)];
    distance = [0 for i in range(256)];
 
    # Initially make all
    # the distances and number
    # of characters visited as 0
    for i in range(256):
        visited[i] = 0;
        distance[i] = 0;   
 
    sum = 0;
 
    for i in range(len(s)):
 
        # Assuming that all the similar
        # characters are located at index 0
 
        # Add visited[s[i]]*i to sum
        # and subtract the distances of
        # characters from index 0
        sum += visited[ord(s[i])] * i - distance[ord(s[i])];
 
        # Increment the number of
        # visited characters
        visited[ord(s[i])] += 1;
 
        # Add the distance of the
        # character from position 0
        # i.e., (i - 0) = i
        distance[ord(s[i])] += i;   
 
    # Return the answer
    return sum;
 
# Driver code
if __name__ == '__main__':
   
    s = "ttt";
 
    # Function call
    print(findSum(s));
 
# This code is contributed by Rajput-Ji

                    

C#

// C# program for the above approach
using System;
 
class GFG{
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a string
static int findSum(String s)
{
    int[] visited = new int[256];
    int[] distance = new int[256];
 
    // Initially make all the distances
    // and number of characters visited as 0
    for(int i = 0; i < 256; i++)
    {
        visited[i] = 0;
        distance[i] = 0;
    }
     
    int sum = 0;
     
    for(int i = 0; i < s.Length; i++)
    {
         
        // Assuming that all the similar
        // characters are located at index 0
 
        // Add visited[s[i]]*i to sum
        // and subtract the distances of
        // characters from index 0
        sum += visited[s[i]] * i -
              distance[s[i]];
 
        // Increment the number of
        // visited characters
        visited[s[i]]++;
 
        // Add the distance of the
        // character from position 0
        // i.e., (i - 0) = i
        distance[s[i]] += i;
    }
 
    // Return the answer
    return sum;
}
 
// Driver code
public static void Main(String[] args)
{
    String s = "ttt";
     
    // Function call
    Console.WriteLine(findSum(s));
}
}
 
// This code is contributed by Amit Katiyar

                    

Javascript

<script>
 
// javascript program for the above approach
 
// Function to calculate the sum
// of distances between occurrences
// of same characters in a string
function findSum(s)
{
    var visited = Array(256).fill(0);
    var distance = Array(256).fill(0);
 
    var sum = 0;
    var i;
    for(i = 0; i < s.length; i++) {
 
        // Assuming that all the similar
        // characters are located at index 0
 
        // Add visited[s[i]]*i to sum
        // and subtract the distances of
        // characters from index 0
        sum += visited[s.charCodeAt(i)] * i
               - distance[s.charCodeAt(i)];
 
        // Increment the number of
        // visited characters
        visited[s.charCodeAt(i)]++;
 
        // Add the distance of the
        // character from position 0
        // i.e., (i - 0) = i
        distance[s.charCodeAt(i)] += i;
    }
 
    // Return the answer
    return sum;
}
 
// Driver code
    var s = "ttt";
 
    // Function call
    document.write(findSum(s));
 
</script>

                    

Output
4






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

Approach: Hash Table

We use the hash table to keep the track of the indices of each character in the string.For each character,iterate over its indices
and calculate the sum of indices between each pair of indices. Last add these sums to the total sum of distances.

Steps:

  • First, create an unordered map to store the indices of each character in the input string S.
  • Then iterate over each character in the map.
  • And for each character, iterate over its indices.
  • Next, calculate the sum of distances between each pair of indices. 
  • add these sums to the total sum of distances.
  • Finally, return the total sum of distances.

Below is the code implementation for the above approach:

C++

// C++ program
#include <iostream>
#include <unordered_map>
#include <vector>
#include <cmath>
 
using namespace std;
 
int sum_of_distances(string S) {
    int n = S.length();
      // create a hash table to store indices
    unordered_map<char, vector<int>> indices;
    int total_distance = 0;
     
    for (int i = 0; i < n; i++) {
        indices[S[i]].push_back(i);
    }
     
    for (auto& indices_list : indices) {
        int m = indices_list.second.size();
        for (int i = 0; i < m; i++) {
            for (int j = i+1; j < m; j++) {
                total_distance += abs(indices_list.second[j] - indices_list.second[i]);
            }
        }
    }
    // return the total sum of distances
    return total_distance;
}
 
// Driver Code
int main() {
    string S = "ababa";
    cout << sum_of_distances(S) << endl;
     
    return 0;
}

                    

Java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class GFG {
 
    public static int sumOfDistances(String S) {
        int n = S.length();
 
        // Create a HashMap to store indices
        Map<Character, List<Integer>> indices = new HashMap<>();
        int totalDistance = 0;
 
        // Populate the HashMap with indices of each character in the string
        for (int i = 0; i < n; i++) {
            char ch = S.charAt(i);
            if (!indices.containsKey(ch)) {
                indices.put(ch, new ArrayList<>());
            }
            indices.get(ch).add(i);
        }
 
        // Calculate the sum of distances between all pairs of indices for each character
        for (Map.Entry<Character, List<Integer>> entry : indices.entrySet()) {
            List<Integer> indicesList = entry.getValue();
            int m = indicesList.size();
            for (int i = 0; i < m; i++) {
                for (int j = i + 1; j < m; j++) {
                    totalDistance += Math.abs(indicesList.get(j) - indicesList.get(i));
                }
            }
        }
 
        // Return the total sum of distances
        return totalDistance;
    }
 
    public static void main(String[] args) {
        String S = "ababa";
        System.out.println(sumOfDistances(S));
    }
}

                    

Python3

def sum_of_distances(S):
    n = len(S)
     
    # Create a dictionary to store indices
    indices = {}
    total_distance = 0
     
    for i in range(n):
        if S[i] not in indices:
            indices[S[i]] = [i]
        else:
            indices[S[i]].append(i)
     
    for indices_list in indices.values():
        m = len(indices_list)
        for i in range(m):
            for j in range(i + 1, m):
                total_distance += abs(indices_list[j] - indices_list[i])
     
    # Return the total sum of distances
    return total_distance
 
# Driver Code
if __name__ == "__main__":
    S = "ababa"
    print(sum_of_distances(S))

                    

C#

using System;
using System.Collections.Generic;
 
class Program
{
    static int SumOfDistances(string S)
    {
        int n = S.Length;
         
        // Create a dictionary to store indices
        Dictionary<char, List<int>> indices = new Dictionary<char, List<int>>();
        int totalDistance = 0;
 
        // Populate the dictionary with character indices
        for (int i = 0; i < n; i++)
        {
            char c = S[i];
            if (!indices.ContainsKey(c))
            {
                indices = new List<int>();
            }
            indices.Add(i);
        }
 
        // Calculate the total sum of distances
        foreach (var indicesList in indices.Values)
        {
            int m = indicesList.Count;
            for (int i = 0; i < m; i++)
            {
                for (int j = i + 1; j < m; j++)
                {
                    totalDistance += Math.Abs(indicesList[j] - indicesList[i]);
                }
            }
        }
 
        // Return the total sum of distances
        return totalDistance;
    }
 
    static void Main()
    {
        string S = "ababa";
        Console.WriteLine(SumOfDistances(S));
    }
}

                    

Javascript

function sumOfDistances(S) {
    const n = S.length;
    // Create an object to store indices
    const indices = {};
 
    let totalDistance = 0;
 
    // Populate the indices object
    for (let i = 0; i < n; i++) {
        const char = S[i];
        if (indices[char]) {
            indices[char].push(i);
        } else {
            indices[char] = [i];
        }
    }
 
    for (const indicesList of Object.values(indices)) {
        const m = indicesList.length;
        for (let i = 0; i < m; i++) {
            for (let j = i + 1; j < m; j++) {
                totalDistance += Math.abs(indicesList[j] - indicesList[i]);
            }
        }
    }
 
    // Return the total sum of distances
    return totalDistance;
}
 
// Driver Code
const S = "ababa";
console.log(sumOfDistances(S));

                    

Output
10







Time Complexity: O(n^2), where n is the length of the input string S.

Auxiliary Space: O(n), where n is the length of the input string S.



Last Updated : 12 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads