Related Articles

Sum of Manhattan distances between repetitions in a String

• Last Updated : 05 Jul, 2021

Given a string S of size N consisting of lowercase characters, the task is to find the sum of Manhattan distance between each pair (i, j) such that i≤j and S[j] = S[i].

Examples:

Input: S = “ababa”
Output: 10
Explanation: The pairs having same characters are: (1, 3), (1, 5), (2, 4) and (3, 5). Therefore, the sum of Manhattan distance will be |3 – 1| + |5 – 1| + |4 – 2| + |5 – 3| = 10

Input: S = “abc”
Output: 0

Naive Approach: The simplest approach is to generate all pairs (i, j) using two nested loops and check for each pair, whether it satisfies the given condition or not. If found to be true, add their distances to the answer. After checking all the pairs, print the answer.

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

Efficient Approach: The approach is similar to finding the Sum of Manhattan distances between all pairs of points. Follow the steps below to solve the problem:

Let the elements of the vector be x1, x2, x3, x4 which represents the indices of the same character.
This character will contribute value = |x2 – x1| + |x3 – x1| + |x4 – x1| + |x3 – x2| + | x4 – x2| + |x4 – x3|

For a sorted array, this can also be written as (x2 + x3 + x4) – 3*x1 + (x3 + x4) – 2*x2 + (x4) – 1*x3

Now, the sum can also be expressed as ∑suffix[i + 1] – (n-i)*xi for i = 1 to n.
where suffix[i+1] is sum of elements from [i+1, n]

Below is the implementation of the above approach:

C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find the sum of the manhattan``// distances between same characters in string``void` `SumofDistances(string s)``{``    ``// Vector to store indices for each``    ``// unique character of the string``    ``vector<``int``> v[26];` `    ``// Append the position of each character``    ``// in their respective vectors``    ``for` `(``int` `i = 0; i < s.size(); i++) {``        ``v[s[i] - ``'a'``].push_back(i);``    ``}` `    ``// Store the required result``    ``int` `ans = 0;` `    ``// Iterate over all the characters``    ``for` `(``int` `i = 0; i < 26; i++) {``        ``int` `sum = 0;` `        ``// Calculate sum of all elements``        ``// present in the vector``        ``for` `(``int` `j = 0; j < v[i].size(); j++) {``            ``sum += v[i][j];``        ``}` `        ``// Traverse the current vector``        ``for` `(``int` `j = 0; j < v[i].size(); j++) {` `            ``// Find suffix[i+1]``            ``sum -= v[i][j];` `            ``// Adding distance of all pairs``            ``// whose first element is i and``            ``// second element belongs to [i+1, n]``            ``ans += (sum``                    ``- (v[i].size() - 1 - j) * (v[i][j]));``        ``}``    ``}` `    ``// Print the result``    ``cout << ans;``}` `// Driver Code``int` `main()``{``    ``// Given Input``    ``string s = ``"ababa"``;` `    ``// Function Call``    ``SumofDistances(s);` `    ``return` `0;``}`

Java

 `// Java program for the above approach``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{``    ` `// Function to find the sum of the manhattan``// distances between same characters in string``static` `void` `SumofDistances(String s)``{``    ` `    ``// Vector to store indices for each``    ``// unique character of the string``    ``ArrayList> v = ``new` `ArrayList<>();``    ` `    ``for``(``int` `i = ``0``; i < ``26``; i++)``        ``v.add(``new` `ArrayList<>());` `    ``// Append the position of each character``    ``// in their respective vectors``    ``for``(``int` `i = ``0``; i < s.length(); i++)``    ``{``        ``v.get(s.charAt(i) - ``'a'``).add(i);``    ``}` `    ``// Store the required result``    ``int` `ans = ``0``;` `    ``// Iterate over all the characters``    ``for``(``int` `i = ``0``; i < ``26``; i++)``    ``{``        ``int` `sum = ``0``;` `        ``// Calculate sum of all elements``        ``// present in the vector``        ``for``(``int` `j = ``0``; j < v.get(i).size(); j++)``        ``{``            ``sum += v.get(i).get(j);``        ``}` `        ``// Traverse the current vector``        ``for``(``int` `j = ``0``; j < v.get(i).size(); j++)``        ``{``            ` `            ``// Find suffix[i+1]``            ``sum -= v.get(i).get(j);` `            ``// Adding distance of all pairs``            ``// whose first element is i and``            ``// second element belongs to [i+1, n]``            ``ans += (sum - (v.get(i).size() - ``1` `- j) *``                          ``(v.get(i).get(j)));``        ``}``    ``}` `    ``// Print the result``   ``System.out.println(ans);``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ` `    ``// Given Input``    ``String s = ``"ababa"``;``    ` `    ``// Function Call``    ``SumofDistances(s);``}``}` `// This code is contributed by offbeat`

Python3

 `# Python program for the above approach`  `#Function to find the sum of the manhattan``#distances between same characters in string``def` `SumofDistances(s):``  ` `    ``# Vector to store indices for each``    ``# unique character of the string``    ``v ``=` `[[] ``for` `i ``in` `range``(``26``)]` `    ``# Append the position of each character``    ``# in their respective vectors``    ``for` `i ``in` `range``(``len``(s)):``        ``v[``ord``(s[i]) ``-` `ord``(``'a'``)].append(i)` `    ``# Store the required result``    ``ans ``=` `0` `    ``# Iterate over all the characters``    ``for` `i ``in` `range``(``26``):``        ``sum` `=` `0` `        ``# Calculate sum of all elements``        ``# present in the vector``        ``for` `j ``in` `range``(``len``(v[i])):``            ``sum` `+``=` `v[i][j]` `        ``# Traverse the current vector``        ``for` `j ``in` `range``(``len``(v[i])):``            ``# Find suffix[i+1]``            ``sum` `-``=` `v[i][j]` `            ``# Adding distance of all pairs``            ``# whose first element is i and``            ``# second element belongs to [i+1, n]``            ``ans ``+``=` `(``sum` `-` `(``len``(v[i]) ``-` `1` `-` `j) ``*` `(v[i][j]))` `    ``# Prthe result``    ``print` `(ans)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``# Given Input``    ``s ``=` `"ababa"` `    ``# Function Call``    ``SumofDistances(s)` `# This code is contributed by mohit kumar 29.`

C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG{` `// Function to find the sum of the manhattan``// distances between same characters in string``static` `void` `SumofDistances(``string` `s)``{``    ` `    ``// Vector to store indices for each``    ``// unique character of the string``    ``List<``int``>[] v = ``new` `List<``int``>[26];``    ``for``(``int` `i = 0; i < 26; i++)``      ``v[i] = ``new` `List<``int``>();` `    ``// Append the position of each character``    ``// in their respective vectors``    ``for``(``int` `i = 0; i < s.Length; i++)``    ``{``        ``v[(``int``)s[i] - 97].Add(i);``    ``}` `    ``// Store the required result``    ``int` `ans = 0;` `    ``// Iterate over all the characters``    ``for``(``int` `i = 0; i < 26; i++)``    ``{``        ``int` `sum = 0;` `        ``// Calculate sum of all elements``        ``// present in the vector``        ``for``(``int` `j = 0; j < v[i].Count; j++)``        ``{``            ``sum += v[i][j];``        ``}` `        ``// Traverse the current vector``        ``for``(``int` `j = 0; j < v[i].Count; j++)``        ``{``            ` `            ``// Find suffix[i+1]``            ``sum -= v[i][j];` `            ``// Adding distance of all pairs``            ``// whose first element is i and``            ``// second element belongs to [i+1, n]``            ``ans += (sum - (v[i].Count - 1 - j) *``                          ``(v[i][j]));``        ``}``    ``}` `    ``// Print the result``    ``Console.Write(ans);``}` `// Driver Code``public` `static` `void` `Main()``{``    ` `    ``// Given Input``    ``string` `s = ``"ababa"``;``    ` `    ``// Function Call``    ``SumofDistances(s);``}``}` `// This code is contributed by ipg2016107`

Javascript

 ``
Output:
`10`

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up