You are given a string s
of lowercase English letters and an integer array shifts
of the same length.
Call the shift()
of a letter, the next letter in the alphabet, (wrapping around so that 'z'
becomes 'a'
).
shift('a') = 'b'
, shift('t') = 'u'
, and shift('z') = 'a'
.Now for each shifts[i] = x
, we want to shift the first i + 1
letters of s
, x
times.
Return the final string after all such shifts to s are applied.
Example 1:
Input: s = "abc", shifts = [3,5,9] Output: "rpl" Explanation: We start with "abc". After shifting the first 1 letters of s by 3, we have "dbc". After shifting the first 2 letters of s by 5, we have "igc". After shifting the first 3 letters of s by 9, we have "rpl", the answer.
Example 2:
Input: s = "aaa", shifts = [1,2,3] Output: "gfd"
Constraints:
1 <= s.length <= 105
s
consists of lowercase English letters.shifts.length == s.length
0 <= shifts[i] <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for shifting letters means we'll try every possible combination of shifts for each letter. We'll go through each possibility, applying the shifts and checking if the final result is what we want. This is like testing every key on a lock until we find the right one.
Here's how the algorithm would work step-by-step:
def shifting_letters_brute_force(original_word, target_word, max_shift):
word_length = len(original_word)
def apply_shifts(word, shifts):
shifted_word = list(word)
for index, shift_value in enumerate(shifts):
shifted_word[index] = chr(((ord(word[index]) - ord('a') + shift_value) % 26) + ord('a'))
return "".join(shifted_word)
# Iterate through all possible lengths of prefixes
for prefix_length in range(word_length + 1):
# Create a shifts array for current prefix length
shifts = [0] * prefix_length
while True:
# Check if shifts make the original word into the target word.
shifted_word = apply_shifts(original_word, shifts)
if shifted_word == target_word:
return shifts
# Increment the last shift, handling carry-over
index = prefix_length - 1
while index >= 0:
shifts[index] += 1
# Carry-over if the shift exceeds the maximum
if shifts[index] > max_shift:
shifts[index] = 0
index -= 1
else:
break
# If all shifts are back to zero, we've exhausted all combinations
if index < 0:
break
# Exhausted all possibilities - no solution
return None
The problem asks us to shift each letter in a string by a certain amount, specified by an array of shifts. Instead of doing the shifts individually, we can calculate the cumulative shift for each letter. Then, we apply these cumulative shifts while wrapping around the alphabet.
Here's how the algorithm would work step-by-step:
def shifting_letters(input_string, shifts):
string_length = len(input_string)
cumulative_shifts = [0] * string_length
cumulative_shifts[-1] = shifts[-1]
# Calculate cumulative shifts from right to left
for index in range(string_length - 2, -1, -1):
cumulative_shifts[index] = (cumulative_shifts[index + 1] + shifts[index])
result_string = ''
for index in range(string_length):
# Normalize the shift value
shift_value = cumulative_shifts[index] % 26
original_char_value = ord(input_string[index]) - ord('a')
# Apply the shift and wrap around the alphabet
new_char_value = (original_char_value + shift_value) % 26
result_string += chr(new_char_value + ord('a'))
return result_string
Case | How to Handle |
---|---|
Null or empty string input | Return an empty string or throw an IllegalArgumentException if null is not allowed as input |
Empty shifts array | Return the original string unchanged if the shifts array is empty. |
String containing non-alphabetic characters | Filter out non-alphabetic characters, throw an exception, or define a character mapping to handle them. |
Large shifts value causing integer overflow | Use modulo operator (%) to wrap the shift value within the alphabet size (26). |
Very long string and shifts array leading to performance issues | Optimize the shifting process using modular arithmetic to avoid unnecessary iterations. |
Shifts array containing both positive and negative shifts | The solution should correctly handle both positive (forward) and negative (backward) shifts. |
A single shift value exceeding the length of the alphabet | Apply the modulo operator to the shift value to ensure it remains within the valid range (0-25). |
Shifts array sums to a value much larger than alphabet size | Accumulate shifts modulo 26 to avoid integer overflow and unnecessary operations. |