3146. Permutation Difference between Two Strings
Problem Description
You are given two strings s
and t
where:
- Every character appears exactly once in string
s
(no duplicates) - String
t
is a permutation of strings
(contains the same characters but possibly in a different order)
The permutation difference is calculated by:
- For each character in the strings, find its position (index) in string
s
and its position in stringt
- Calculate the absolute difference between these two positions
- Sum up all these absolute differences for all characters
Your task is to return this permutation difference value.
For example, if a character 'a' appears at index 2 in string s
and at index 5 in string t
, the contribution of 'a' to the permutation difference would be |2 - 5| = 3
. You need to calculate this for all characters and return the total sum.
Intuition
Since we need to find the absolute difference between positions of the same character in two strings, the key insight is that we need a way to quickly look up where each character appears in string s
.
Think about it this way: as we go through string t
, for each character we encounter, we need to know "where was this character in string s
?" This suggests we should preprocess string s
to store the position of each character.
A hash table (dictionary) is perfect for this - we can map each character to its index in string s
. Since each character appears exactly once in s
, we don't have to worry about duplicate characters overwriting positions.
Once we have this mapping, the solution becomes straightforward:
- Build a dictionary
d
whered[character] = index in s
- Iterate through string
t
with its indices - For each character in
t
at positioni
, look up its position ins
using our dictionary - Calculate
|d[character] - i|
and add it to our running sum
This approach is efficient because we only need to traverse each string once - once to build the dictionary from s
, and once to calculate the sum while traversing t
. The time complexity is O(n)
where n
is the length of the strings.
Solution Approach
The solution uses a hash table to efficiently map characters to their positions in string s
.
Step 1: Build the position mapping
We create a dictionary d
that stores the index of each character in string s
:
d = {c: i for i, c in enumerate(s)}
This dictionary comprehension iterates through string s
with enumerate()
, which gives us both the index i
and character c
. For example, if s = "abc"
, the dictionary would be {'a': 0, 'b': 1, 'c': 2}
.
Step 2: Calculate the permutation difference
We traverse string t
and calculate the sum of absolute differences:
return sum(abs(d[c] - i) for i, c in enumerate(t))
This generator expression:
- Uses
enumerate(t)
to get each characterc
and its indexi
in stringt
- Looks up the position of character
c
in strings
usingd[c]
- Calculates the absolute difference:
abs(d[c] - i)
- The
sum()
function adds up all these absolute differences
Example walkthrough:
If s = "abc"
and t = "bac"
:
- Build dictionary:
d = {'a': 0, 'b': 1, 'c': 2}
- Process
t
:- Character 'b' at index 0 in
t
, at index 1 ins
:|1 - 0| = 1
- Character 'a' at index 1 in
t
, at index 0 ins
:|0 - 1| = 1
- Character 'c' at index 2 in
t
, at index 2 ins
:|2 - 2| = 0
- Character 'b' at index 0 in
- Total sum:
1 + 1 + 0 = 2
The solution has O(n)
time complexity for building the dictionary and calculating the sum, and O(n)
space complexity for storing the dictionary.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's work through a concrete example with s = "acb"
and t = "cab"
.
Step 1: Build the position mapping from string s
We create a dictionary that maps each character to its index in s
:
- 'a' is at index 0
- 'c' is at index 1
- 'b' is at index 2
So our dictionary becomes: d = {'a': 0, 'c': 1, 'b': 2}
Step 2: Process string t and calculate differences
Now we traverse t = "cab"
character by character:
-
Index 0: Character 'c'
- Position in
t
: 0 - Position in
s
(from dictionary):d['c'] = 1
- Contribution:
|1 - 0| = 1
- Position in
-
Index 1: Character 'a'
- Position in
t
: 1 - Position in
s
(from dictionary):d['a'] = 0
- Contribution:
|0 - 1| = 1
- Position in
-
Index 2: Character 'b'
- Position in
t
: 2 - Position in
s
(from dictionary):d['b'] = 2
- Contribution:
|2 - 2| = 0
- Position in
Step 3: Sum up all contributions
Total permutation difference = 1 + 1 + 0 = 2
This means the characters in t
are collectively displaced by 2 positions compared to their original positions in s
.
Solution Implementation
1class Solution:
2 def findPermutationDifference(self, s: str, t: str) -> int:
3 # Create a dictionary mapping each character in string s to its index position
4 char_to_index_in_s = {char: index for index, char in enumerate(s)}
5
6 # Calculate the sum of absolute differences between positions
7 # For each character in t, find its position in s and compute |pos_in_s - pos_in_t|
8 total_difference = sum(abs(char_to_index_in_s[char] - index)
9 for index, char in enumerate(t))
10
11 return total_difference
12
1class Solution {
2 public int findPermutationDifference(String s, String t) {
3 // Array to store the index position of each character in string s
4 // Index represents character (a=0, b=1, ..., z=25)
5 int[] indexInS = new int[26];
6
7 // Get the length of the strings (both s and t have the same length)
8 int length = s.length();
9
10 // Store the index position of each character from string s
11 for (int i = 0; i < length; ++i) {
12 char currentChar = s.charAt(i);
13 int charIndex = currentChar - 'a'; // Convert character to array index (0-25)
14 indexInS[charIndex] = i;
15 }
16
17 // Calculate the sum of absolute differences
18 int totalDifference = 0;
19
20 // For each character in string t, find the absolute difference
21 // between its position in t and its position in s
22 for (int i = 0; i < length; ++i) {
23 char currentChar = t.charAt(i);
24 int charIndex = currentChar - 'a'; // Convert character to array index (0-25)
25 int positionInS = indexInS[charIndex];
26 int positionInT = i;
27
28 // Add the absolute difference to the total
29 totalDifference += Math.abs(positionInS - positionInT);
30 }
31
32 return totalDifference;
33 }
34}
35
1class Solution {
2public:
3 int findPermutationDifference(string s, string t) {
4 // Array to store the index position of each character in string s
5 // Index represents character (a=0, b=1, ..., z=25)
6 int charIndexInS[26] = {0};
7
8 // Get the length of the strings (both have same length)
9 int length = s.size();
10
11 // Record the position of each character in string s
12 for (int i = 0; i < length; ++i) {
13 charIndexInS[s[i] - 'a'] = i;
14 }
15
16 // Calculate the total permutation difference
17 int totalDifference = 0;
18
19 // For each character in string t, find its position difference with string s
20 for (int i = 0; i < length; ++i) {
21 // Get the character from string t
22 char currentChar = t[i];
23
24 // Calculate absolute difference between positions in s and t
25 // charIndexInS[currentChar - 'a'] gives position in s
26 // i is the current position in t
27 totalDifference += abs(charIndexInS[currentChar - 'a'] - i);
28 }
29
30 return totalDifference;
31 }
32};
33
1/**
2 * Finds the total permutation difference between two strings.
3 * The permutation difference is the sum of absolute differences between
4 * the positions of each character in string s and string t.
5 *
6 * @param s - The first string (containing lowercase letters a-z)
7 * @param t - The second string (a permutation of s)
8 * @returns The sum of absolute position differences for all characters
9 */
10function findPermutationDifference(s: string, t: string): number {
11 // Array to store the position of each character in string s
12 // Index represents character (a=0, b=1, ..., z=25)
13 const characterPositionsInS: number[] = Array(26).fill(0);
14
15 // Get the length of the strings
16 const stringLength: number = s.length;
17
18 // Record the position of each character in string s
19 for (let index = 0; index < stringLength; ++index) {
20 // Convert character to array index (a=0, b=1, etc.)
21 const charIndex: number = s.charCodeAt(index) - 97;
22 characterPositionsInS[charIndex] = index;
23 }
24
25 // Calculate the total permutation difference
26 let totalDifference: number = 0;
27
28 // For each character in string t, find its position difference with string s
29 for (let index = 0; index < stringLength; ++index) {
30 // Get the character's index in the array
31 const charIndex: number = t.charCodeAt(index) - 97;
32
33 // Add the absolute difference between positions in s and t
34 const positionInS: number = characterPositionsInS[charIndex];
35 totalDifference += Math.abs(positionInS - index);
36 }
37
38 return totalDifference;
39}
40
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the string s
(or equivalently, the length of string t
since they are permutations of each other). This is because:
- Building the dictionary
d
requires iterating through strings
once:O(n)
- The sum comprehension iterates through string
t
once, and for each character, the dictionary lookupd[c]
isO(1)
:O(n)
- Total:
O(n) + O(n) = O(n)
The space complexity is O(|Σ|)
, where Σ
is the character set. Since the problem involves permutations of the same characters, the dictionary d
stores at most as many key-value pairs as there are unique characters in string s
. For lowercase English letters, |Σ| ≤ 26
, making the space complexity O(1)
in practical terms.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Assuming Character Uniqueness Without Validation
The most common pitfall is trusting that the input strings truly have unique characters as stated in the problem. In real-world scenarios or modified problem variants, duplicate characters could cause incorrect results or runtime errors.
The Issue:
If string s
has duplicate characters, the dictionary comprehension {c: i for i, c in enumerate(s)}
will only store the last occurrence of each character. This leads to incorrect position mappings.
Example of the problem:
s = "aba" # 'a' appears twice t = "baa" # Dictionary becomes {'a': 2, 'b': 1} - first 'a' at index 0 is overwritten!
Solution: Add validation or handle duplicates explicitly:
class Solution:
def findPermutationDifference(self, s: str, t: str) -> int:
# Validate uniqueness (optional but safer)
if len(s) != len(set(s)):
raise ValueError("String s contains duplicate characters")
char_to_index_in_s = {char: index for index, char in enumerate(s)}
total_difference = sum(abs(char_to_index_in_s[char] - index)
for index, char in enumerate(t))
return total_difference
2. Missing Character in Translation
Another pitfall occurs when string t
contains a character not present in string s
, which would cause a KeyError
when accessing char_to_index_in_s[char]
.
Example of the problem:
s = "abc" t = "abd" # 'd' is not in s # This will raise KeyError: 'd'
Solution:
Use .get()
method with a default value or add validation:
class Solution:
def findPermutationDifference(self, s: str, t: str) -> int:
char_to_index_in_s = {char: index for index, char in enumerate(s)}
# Option 1: Validate that t is truly a permutation
if set(s) != set(t):
raise ValueError("String t is not a permutation of string s")
# Option 2: Use get() to handle missing keys gracefully
# (though this changes the problem semantics)
total_difference = sum(abs(char_to_index_in_s.get(char, index) - index)
for index, char in enumerate(t))
return total_difference
3. Performance Degradation with Large Strings
While the current solution is O(n), repeatedly accessing the dictionary in a tight loop can have overhead. For extremely large strings, consider whether the problem allows for optimization through vectorization or parallel processing.
Best Practice:
The current solution is already optimal for the given constraints. However, always verify that the dictionary lookup approach is faster than alternative methods (like using s.index(char)
directly) through benchmarking with your specific data sizes.
Which of the following is a min heap?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!