1844. Replace All Digits with Characters
Problem Description
You are given a string s
where:
- Characters at even indices (0, 2, 4, ...) are lowercase English letters
- Characters at odd indices (1, 3, 5, ...) are digits
Your task is to transform the string by replacing each digit with a new character. The replacement follows a specific rule based on a shift
operation.
The shift(c, x)
operation takes:
c
: a character (letter)x
: a digit (number)
It returns the character that is x
positions after c
in the alphabet. For example:
shift('a', 5)
returns'f'
(because 'f' is 5 positions after 'a')shift('x', 0)
returns'x'
(because 0 positions after 'x' is still 'x')
For each odd index i
in the string, you need to:
- Take the character at position
i-1
(which will be a letter) - Take the digit at position
i
- Replace the digit at position
i
with the result ofshift(s[i-1], s[i])
The problem guarantees that the shift operation will never produce a character beyond 'z'.
Example walkthrough:
If s = "a1c1e1"
:
- Index 1: Replace '1' with
shift('a', 1)
= 'b' - Index 3: Replace '1' with
shift('c', 1)
= 'd' - Index 5: Replace '1' with
shift('e', 1)
= 'f' - Result:
"abcdef"
The solution converts the string to a list for easy modification, iterates through odd indices, applies the shift operation by using ASCII values (ord
and chr
functions), and joins the list back into a string.
Intuition
The problem is straightforward - we need to process the string and replace digits at odd positions. The key insight is recognizing that we only need to modify characters at odd indices, while characters at even indices remain unchanged.
Since we need to replace each digit with a character that's a certain number of positions after the previous character, we can think of this as a character arithmetic problem. In programming, characters are represented by ASCII values, which are numbers. For example, 'a' has ASCII value 97, 'b' has value 98, and so on.
To shift a character by x
positions, we can:
- Convert the character to its ASCII value using
ord()
- Add the digit value to it
- Convert the result back to a character using
chr()
For instance, to get the character 3 positions after 'a':
ord('a')
gives us 97- Add 3 to get 100
chr(100)
gives us 'd'
The natural approach is to iterate through the string, but only process odd indices (1, 3, 5, ...). For each odd index i
, we look at the character at i-1
(which is guaranteed to be a letter) and the digit at position i
, then perform the shift operation.
Since strings in Python are immutable (cannot be changed directly), we convert the string to a list first, make our modifications, and then join it back into a string. This allows us to modify individual characters efficiently.
The iteration pattern range(1, len(s), 2)
elegantly gives us all odd indices starting from 1, stepping by 2 each time, which is exactly what we need to process only the positions containing digits.
Solution Approach
The solution uses a simulation approach to process the string character by character. Here's the step-by-step implementation:
Step 1: Convert string to a mutable list
s = list(s)
Since Python strings are immutable, we convert the string to a list to allow in-place modifications. This gives us O(1) access to modify individual characters.
Step 2: Iterate through odd indices
for i in range(1, len(s), 2):
We start from index 1 (the first odd index) and step by 2 to visit only odd indices (1, 3, 5, ...). This ensures we only process positions that contain digits.
Step 3: Apply the shift operation
s[i] = chr(ord(s[i - 1]) + int(s[i]))
For each odd index i
:
s[i - 1]
gets the character at the previous (even) index, which is a letterord(s[i - 1])
converts this letter to its ASCII valueint(s[i])
converts the digit character at positioni
to its numeric value- We add these two values together
chr()
converts the resulting ASCII value back to a character- The result replaces the digit at position
i
Step 4: Join and return the result
return ''.join(s)
After all replacements are complete, we join the list back into a string and return it.
Example Trace:
For s = "a1c1e1"
:
- Initial list:
['a', '1', 'c', '1', 'e', '1']
- i = 1:
s[1] = chr(ord('a') + 1) = chr(97 + 1) = chr(98) = 'b'
- i = 3:
s[3] = chr(ord('c') + 1) = chr(99 + 1) = chr(100) = 'd'
- i = 5:
s[5] = chr(ord('e') + 1) = chr(101 + 1) = chr(102) = 'f'
- Final result:
"abcdef"
Time Complexity: O(n) where n is the length of the string, as we iterate through approximately n/2 characters.
Space Complexity: O(n) for the list conversion, though this could be considered O(1) extra space if we don't count the output string construction.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with the example s = "m2u4y0"
:
Initial Setup:
- Convert string to list:
['m', '2', 'u', '4', 'y', '0']
- We'll process indices 1, 3, and 5 (the odd positions containing digits)
Processing Index 1:
- Current digit: '2' at index 1
- Previous letter: 'm' at index 0
- Apply shift operation:
shift('m', 2)
- ASCII value of 'm' = 109
- Add digit value 2: 109 + 2 = 111
- Convert back to character: chr(111) = 'o'
- Replace '2' with 'o':
['m', 'o', 'u', '4', 'y', '0']
Processing Index 3:
- Current digit: '4' at index 3
- Previous letter: 'u' at index 2
- Apply shift operation:
shift('u', 4)
- ASCII value of 'u' = 117
- Add digit value 4: 117 + 4 = 121
- Convert back to character: chr(121) = 'y'
- Replace '4' with 'y':
['m', 'o', 'u', 'y', 'y', '0']
Processing Index 5:
- Current digit: '0' at index 5
- Previous letter: 'y' at index 4
- Apply shift operation:
shift('y', 0)
- ASCII value of 'y' = 121
- Add digit value 0: 121 + 0 = 121
- Convert back to character: chr(121) = 'y'
- Replace '0' with 'y':
['m', 'o', 'u', 'y', 'y', 'y']
Final Result:
- Join the list back to string:
"mouyy"
The key insight is that we only modify odd-indexed positions, replacing each digit with a character that's shifted from the preceding letter by the digit's value.
Solution Implementation
1class Solution:
2 def replaceDigits(self, s: str) -> str:
3 """
4 Replace every digit at odd indices with the character obtained by
5 shifting the previous character by the digit's value.
6
7 Args:
8 s: Input string containing lowercase letters and digits
9
10 Returns:
11 Modified string with digits replaced by shifted characters
12 """
13 # Convert string to list for in-place modification
14 char_list = list(s)
15
16 # Iterate through odd indices (1, 3, 5, ...)
17 for i in range(1, len(char_list), 2):
18 # Get the previous character (at even index)
19 prev_char = char_list[i - 1]
20
21 # Get the digit value at current position
22 shift_value = int(char_list[i])
23
24 # Calculate new character by shifting previous character
25 # ord() gets ASCII value, add shift, chr() converts back to character
26 new_char = chr(ord(prev_char) + shift_value)
27
28 # Replace digit with the new character
29 char_list[i] = new_char
30
31 # Convert list back to string and return
32 return ''.join(char_list)
33
1class Solution {
2 /**
3 * Replaces digits at odd indices with the character that is
4 * the digit's value positions after the preceding character.
5 *
6 * @param s the input string containing alternating letters and digits
7 * @return the string with digits replaced by shifted characters
8 */
9 public String replaceDigits(String s) {
10 // Convert string to character array for in-place modification
11 char[] charArray = s.toCharArray();
12
13 // Iterate through odd indices (1, 3, 5, ...) where digits are located
14 for (int index = 1; index < charArray.length; index += 2) {
15 // Get the character at the previous position (even index)
16 char previousChar = charArray[index - 1];
17
18 // Convert current digit character to its numeric value
19 int shiftAmount = charArray[index] - '0';
20
21 // Replace digit with the character shifted from the previous character
22 charArray[index] = (char) (previousChar + shiftAmount);
23 }
24
25 // Convert the modified character array back to string and return
26 return String.valueOf(charArray);
27 }
28}
29
1class Solution {
2public:
3 string replaceDigits(string s) {
4 int stringLength = s.size();
5
6 // Iterate through odd indices (1, 3, 5, ...)
7 // These positions contain digits that need to be replaced
8 for (int i = 1; i < stringLength; i += 2) {
9 // Get the character at the previous position (even index)
10 char previousChar = s[i - 1];
11
12 // Convert the digit character at current position to its numeric value
13 int shiftAmount = s[i] - '0';
14
15 // Apply the shift operation:
16 // Replace digit with the character that is 'shiftAmount' positions
17 // after the previous character in the alphabet
18 s[i] = previousChar + shiftAmount;
19 }
20
21 return s;
22 }
23};
24
1/**
2 * Replaces every digit in the string with a character formed by shifting
3 * the previous character by the digit's value in the alphabet.
4 * Characters at even indices remain unchanged, while characters at odd indices
5 * (which should be digits) are replaced with the result of shifting the previous character.
6 *
7 * @param s - The input string containing lowercase letters and digits
8 * @returns The transformed string with digits replaced
9 */
10function replaceDigits(s: string): string {
11 // Get the length of the input string
12 const stringLength: number = s.length;
13
14 // Convert string to array for easier character manipulation
15 const resultArray: string[] = [...s];
16
17 // Iterate through odd indices (where digits should be located)
18 for (let index = 1; index < stringLength; index += 2) {
19 // Get the previous character's ASCII code
20 const previousCharCode: number = resultArray[index - 1].charCodeAt(0);
21
22 // Convert current digit character to number
23 const shiftAmount: number = Number(resultArray[index]);
24
25 // Calculate new character by shifting previous character by digit amount
26 const newCharCode: number = previousCharCode + shiftAmount;
27
28 // Replace digit with the new character
29 resultArray[index] = String.fromCharCode(newCharCode);
30 }
31
32 // Join the array back into a string and return
33 return resultArray.join('');
34}
35
Time and Space Complexity
Time Complexity: O(n)
, where n
is the length of the string s
. The algorithm iterates through the string once with a for loop that visits approximately n/2
elements (every odd index), and each operation inside the loop (character conversion, addition, and assignment) takes O(1)
time. Therefore, the overall time complexity is O(n)
.
Space Complexity: O(n)
for the total space used, but if we ignore the space consumption of the answer (as mentioned in the reference), the space complexity is O(1)
. The conversion of the string to a list creates a new list of size n
, which is necessary for the output. However, aside from this required output space, no additional data structures that grow with input size are used - only constant extra variables are needed for the loop and character operations.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Attempting Direct String Modification
One of the most common mistakes is trying to modify the string directly without converting it to a list first:
# WRONG - This will raise TypeError
def replaceDigits(self, s: str) -> str:
for i in range(1, len(s), 2):
s[i] = chr(ord(s[i - 1]) + int(s[i])) # Error: strings are immutable
return s
Solution: Always convert the string to a list first for modification, then join it back.
2. Incorrect Index Range or Step
Developers might accidentally iterate through all indices or use the wrong starting point:
# WRONG - Processes even indices instead of odd
for i in range(0, len(s), 2): # Starts at 0, not 1
s[i] = chr(ord(s[i - 1]) + int(s[i])) # s[i-1] would be out of bounds when i=0
# WRONG - Processes all indices
for i in range(len(s)): # Should only process odd indices
if i % 2 == 1: # Extra check needed, less efficient
s[i] = chr(ord(s[i - 1]) + int(s[i]))
Solution: Use range(1, len(s), 2)
to directly iterate through odd indices only.
3. Forgetting Type Conversions
Missing the conversion from string digit to integer or ASCII operations:
# WRONG - Concatenating character with string digit
s[i] = s[i - 1] + s[i] # Results in string concatenation, not shifting
# WRONG - Adding character directly to digit
s[i] = chr(s[i - 1] + int(s[i])) # Missing ord() conversion
Solution: Remember the conversion chain: character → ord() → ASCII value → add shift → chr() → character
4. Out of Bounds ASCII Values
While the problem guarantees no overflow beyond 'z', in practice you might want to handle wraparound:
# More robust solution with wraparound handling
def replaceDigits(self, s: str) -> str:
s = list(s)
for i in range(1, len(s), 2):
shift_value = int(s[i])
new_ascii = ord(s[i - 1]) + shift_value
# Handle potential wraparound (though not needed per problem constraints)
if new_ascii > ord('z'):
new_ascii = ord('a') + (new_ascii - ord('z') - 1)
s[i] = chr(new_ascii)
return ''.join(s)
5. Edge Case Handling
Not considering edge cases like empty strings or single character strings:
# Better with edge case handling
def replaceDigits(self, s: str) -> str:
if len(s) <= 1: # No digits to replace
return s
s = list(s)
for i in range(1, len(s), 2):
s[i] = chr(ord(s[i - 1]) + int(s[i]))
return ''.join(s)
Solution: While the problem likely guarantees valid input, adding simple length checks makes the code more robust for real-world applications.
Which of the following shows the order of node visit in a Breadth-first Search?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!