Meta Data#
Difficulty: medium First Attempt: 2025-04-20
- Total time: 30:00.00
Intuition#
This is a prefix sum problem. My first thought was to create a prefix sum array of the same length as s
and iterate through the shifts
, storing the forward or backward shift information into ps
at each position. It looked like this:
for (start, end, direction) in shifts:
for i in range(start, end+1):
if direction: # forward
ps[i] += 1
else:
ps[i] -= 1
But this is an O(n^2)
operation. When the length of s
is large (up to 5 * 10^4
per the constraints), it will cause a TLE. Then I realized this is actually a difference array problem. I can just store the index changes for forward or backward shifts to avoid the O(n^2)
time complexity.
Approach#
TLE Solution#
class Solution:
def shiftingLetters(self, s: str, shifts: List[List[int]]) -> str:
n = len(s)
ps = [0]*n
for (start, end, direction) in shifts:
for i in range(start, end+1):
if direction: # forward
ps[i] += 1
else:
ps[i] -= 1
result = []
for i in range(n):
diff_with_a = ord(s[i]) - ord('a')
diff = (ps[i] % 26 + diff_with_a) % 26
result.append(chr(ord('a') + diff))
return "".join(result)
Optimized Solution Using Difference Array#
class Solution:
def shiftingLetters(self, s: str, shifts: List[List[int]]) -> str:
n = len(s)
ps = [0]*(n+1)
for (start, end, direction) in shifts:
if direction: # forward
ps[start] += 1
if end < n:
ps[end+1] -= 1
else: # backward
ps[start] -= 1
if end < n:
ps[end+1] += 1
result = []
count = 0
for i in range(n):
count += ps[i]
diff_with_a = ord(s[i]) - ord('a')
diff = (count % 26 + diff_with_a) % 26
result.append(chr(ord('a') + diff))
return "".join(result)
Findings#
First time solving difference array problem
Encountered Problems#
I encountered a problem when handling the ord()
values. I initially didn’t separate 'a'
from the difference, which caused the character to go beyond 'z'
after applying the shift.