Introduction
In LeetCode 249: Group Shifted Strings, we’re asked to group together strings that belong to the same shifting sequence.
Two strings are considered part of the same group if the letters in one string can be uniformly shifted to match the other.
This problem tests your understanding of string manipulation, modular arithmetic, and pattern grouping.
Problem Statement
We can shift a string by shifting each of its characters to its successive character.
For example: "abc"
→ "bcd"
, "xyz"
→ "yza"
(wrapping around is allowed).
Given an array of strings, group all the strings that belong to the same shifting sequence.
Example:
vbnet
Input: ["abc","bcd","acef","xyz","az","ba","a","z"]
Output: [["abc","bcd","xyz"],["az","ba"],["acef"],["a","z"]]
Step-by-Step Solution in Python
Step 1: Understand the Shifting Pattern
- In
"abc"
→ the shift pattern is [1, 1]
because:
- b - a = 1
- c - b = 1
- In
"bcd"
→ shift pattern is also [1, 1]
- In
"az"
→ shift is [25]
(z - a = -1 mod 26 = 25)
So we need to normalize each string into a pattern and use that as a hashable key.
Step 2: Use a Hash Map to Group
- Use a dictionary where:
- Key: shift pattern (a tuple)
- Value: list of strings with that shift pattern
Step 3: Code It
python
from collections import defaultdict
def groupStrings(strings: list[str]) -> list[list[str]]:
def get_shift_pattern(s: str):
# For single character, return empty pattern
if len(s) == 1:
return ()
pattern = []
for i in range(1, len(s)):
diff = (ord(s[i]) - ord(s[i - 1])) % 26
pattern.append(diff)
return tuple(pattern)
groups = defaultdict(list)
for word in strings:
pattern = get_shift_pattern(word)
groups[pattern].append(word)
return list(groups.values())
Explanation of the Code
get_shift_pattern
Function:
- Converts each word into a tuple of differences between adjacent characters, modulo 26 to handle wrap-around.
- Use
defaultdict(list)
:
- Automatically initializes a new list for new patterns.
- Group Words:
- Append each word to the list corresponding to its shift pattern.
- Return Result:
- Convert the grouped values into a list of lists.
Example Breakdown
Input: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"]
"abc"
→ [1, 1]
"bcd"
→ [1, 1]
"xyz"
→ [1, 1]
→ Group: ["abc", "bcd", "xyz"]
"az"
→ [25]
"ba"
→ [25]
→ Group: ["az", "ba"]
"acef"
→ [2, 3, 1]
→ Group: ["acef"]
"a"
and "z"
→ []
→ Group: ["a", "z"]
Time and Space Complexity
- Time Complexity: O(n * k), where:
- n = number of strings
- k = average length of a string (to compute pattern)
- Space Complexity: O(n), for storing the groups
Conclusion
LeetCode 249 challenges your ability to think in terms of patterns rather than values. It’s a classic twist on problems like grouping anagrams, but with a Caesar cipher flavor.
By converting each string into a shift pattern, we efficiently group them using a hash map.