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
This problem involves shifting characters in a string based on cumulative shift values. The most efficient approach uses a suffix sum technique to avoid redundant calculations.
Problem Overview:
We're given a string s
containing lowercase English letters and an integer array shifts
of the same length. shifts[i]
represents the number of times to shift the first i+1
characters of s
. Shifting a letter means moving it one position forward in the alphabet, wrapping around from 'z' to 'a'. The goal is to determine the final string after applying all shifts.
Approach: Suffix Sum
Instead of iterating through the string multiple times to apply each individual shift, we can calculate the cumulative shift for each character beforehand. This is done efficiently using a suffix sum approach.
Reverse Iteration: We iterate through the shifts
array from right to left (from the last element to the first).
Cumulative Sum: We maintain a variable t
that accumulates the shift values. For each index i
, t
represents the total shift applied to character s[i]
. We update t
by adding shifts[i]
in each iteration.
Shift Application: For each character s[i]
, we calculate the final shifted character using the formula: (s[i] - 'a' + t) % 26 + 'a'
. This handles the wrapping around of the alphabet.
String Reconstruction: Finally, we construct the final string by concatenating the shifted characters.
Time Complexity: O(n), where n is the length of the string s
. We iterate through the string and the shifts
array once.
Space Complexity: O(1) if we modify the string in-place. Otherwise O(n) to store a new string.
Code Examples:
Python
def shiftingLetters(s, shifts):
n = len(s)
s_list = list(s) # Convert string to list for mutability
t = 0
for i in range(n - 1, -1, -1):
t += shifts[i]
shifted_char = chr(((ord(s_list[i]) - ord('a') + t) % 26) + ord('a'))
s_list[i] = shifted_char
return "".join(s_list)
Java
class Solution {
public String shiftingLetters(String s, int[] shifts) {
char[] charArray = s.toCharArray();
int n = charArray.length;
long totalShift = 0; //Use long to prevent overflow
for (int i = n - 1; i >= 0; i--) {
totalShift += shifts[i];
int shiftedChar = (charArray[i] - 'a' + (int)totalShift) % 26 + 'a';
charArray[i] = (char) shiftedChar;
}
return new String(charArray);
}
}
C++
string shiftingLetters(string s, vector<int>& shifts) {
long long totalShift = 0; // Use long long to prevent overflow
for (int i = s.length() - 1; i >= 0; --i) {
totalShift += shifts[i];
s[i] = 'a' + (s[i] - 'a' + totalShift) % 26;
}
return s;
}
Go
func shiftingLetters(s string, shifts []int) string {
runes := []rune(s)
n := len(runes)
totalShift := 0
for i := n - 1; i >= 0; i-- {
totalShift += shifts[i]
runes[i] = 'a' + rune((int(runes[i]-'a') + totalShift)%26)
}
return string(runes)
}
These code examples all implement the suffix sum approach, ensuring an optimal time complexity of O(n). The choice of language might slightly affect constant factors in performance but the algorithmic efficiency remains the same.