Description
You are given a string s of lowercase English letters and a 2D integer array shifts where shifts[i] = [starti, endi, directioni]. For every i, shift the characters in s from the index starti to the index endi (inclusive) forward if directioni = 1, or shift the characters backward if directioni = 0.
Shifting a character forward means replacing it with the next letter in the alphabet (wrapping around so that ‘z’ becomes ‘a’). Similarly, shifting a character backward means replacing it with the previous letter in the alphabet (wrapping around so that ‘a’ becomes ‘z’).
Return the final string after all such shifts to s are applied.
Example 1:
Input: s = "abc", shifts = [[0,1,0],[1,2,1],[0,2,1]]
Output: "ace"
Explanation: Firstly, shift the characters from index 0 to index 1 backward. Now s = "zac".
Secondly, shift the characters from index 1 to index 2 forward. Now s = "zbd".
Finally, shift the characters from index 0 to index 2 forward. Now s = "ace".
Example 2:
Input: s = "dztz", shifts = [[0,0,0],[1,1,1]]
Output: "catz"
Explanation: Firstly, shift the characters from index 0 to index 0 backward. Now s = "cztz".
Finally, shift the characters from index 1 to index 1 forward. Now s = "catz".
Constraints:
1 <= s.length, shifts.length <= 5 * 10^4
shifts[i].length == 3
0 <= starti <= endi < s.length
0 <= directioni <= 1
s consists of lowercase English letters.
Solution
Flatten shifts first, for start
and end
position, record the change of shifts. Then iterate the string from left to right, use cur_direction
to keep track of how we should shift the character.
When we need to shift a
1 step forward or backward, because a
does not start from 0
, so remember to use chr - ord('a')
first. To be more clear:
newChar
=
‘a’ + (oldChar - ‘a’ + numberOfShifts) mod 26
\text{newChar} = \text{`a' + (oldChar - `a' + numberOfShifts) mod 26}
newChar=‘a’ + (oldChar - ‘a’ + numberOfShifts) mod 26
Time complexity:
o
(
n
)
o(n)
o(n)
Space complexity:
o
(
n
)
o(n)
o(n)
Code
class Solution:
def shiftingLetters(self, s: str, shifts: List[List[int]]) -> str:
direction_changes = {}
for start, end, shift_dir in shifts:
direction_changes[start] = direction_changes.get(start, 0) + 1 * (-1 if shift_dir == 0 else 1)
direction_changes[end + 1] = direction_changes.get(end + 1, 0) + (-1) * (-1 if shift_dir == 0 else 1)
res = []
cur_direction = 0
for i in range(len(s)):
cur_direction += direction_changes.get(i, 0)
new_char = chr((ord(s[i]) - ord('a') + cur_direction) % 26 + ord('a'))
res.append(new_char)
return ''.join(res)