557. Reverse Words in a String III
Problem Description
Given a string s
that contains words separated by spaces, you need to reverse the characters within each individual word while keeping the words in their original positions and preserving all whitespace.
For example, if the input string is "Let's take LeetCode contest"
, each word should have its characters reversed individually:
"Let's"
becomes"s'teL"
"take"
becomes"ekat"
"LeetCode"
becomes"edoCteeL"
"contest"
becomes"tsetnoc"
The final output would be "s'teL ekat edoCteeL tsetnoc"
.
The key requirements are:
- Reverse the characters in each word
- Keep the words in their original order
- Preserve the original spacing between words
The solution splits the string by spaces using s.split()
, which creates a list of words. Then for each word t
, it reverses the characters using Python's slice notation t[::-1]
. Finally, it joins all the reversed words back together with spaces using " ".join()
.
Intuition
When we look at this problem, we need to perform an operation on each word independently while maintaining the overall structure of the sentence. This naturally suggests breaking the problem down into smaller parts.
The first observation is that we need to process each word separately. Since words are separated by spaces, we can use the space character as a delimiter to identify individual words. This leads us to think about splitting the string into a list of words.
Once we have individual words, the task becomes straightforward - reverse each word. In Python, reversing a string can be elegantly done using slice notation [::-1]
, which reads the string backwards.
After reversing each word, we need to reconstruct the sentence. Since we want to maintain the original spacing (single spaces between words), we can join the reversed words back together with spaces.
The beauty of this approach is that split()
without arguments automatically handles multiple spaces by treating consecutive spaces as a single delimiter and returns only the non-empty words. When we join them back with a single space, we get the desired output format.
This leads to a clean one-liner solution: split the string into words, reverse each word, and join them back. The entire process maintains the word order since we process them in sequence and only modify the internal character order of each word.
Learn more about Two Pointers patterns.
Solution Approach
The implementation follows a straightforward simulation approach where we process the string in three steps:
-
Split the string into words: We use
s.split()
to break the input string into a list of words. Thesplit()
method without arguments automatically splits by any whitespace and removes empty strings from the result. -
Reverse each word: For each word
t
in the list, we apply Python's slice notationt[::-1]
to reverse it. The slice[::-1]
creates a new string that starts from the end and moves backwards with a step of -1, effectively reversing the string. -
Join the reversed words: We use
" ".join()
to concatenate all reversed words back into a single string with single spaces between them.
The complete solution combines these steps into a single line using a generator expression:
return " ".join(t[::-1] for t in s.split())
Here's how it works step by step:
s.split()
produces a list like["Let's", "take", "LeetCode", "contest"]
- The generator expression
t[::-1] for t in s.split()
iterates through each word and reverses it - This produces reversed words:
"s'teL"
,"ekat"
,"edoCteeL"
,"tsetnoc"
" ".join()
combines these reversed words with spaces:"s'teL ekat edoCteeL tsetnoc"
The time complexity is O(n)
where n
is the length of the string, as we need to process each character once. The space complexity is also O(n)
for storing the split words and the final result string.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example with the input string "hello world"
.
Step 1: Split the string into words
- Input:
"hello world"
- After
s.split()
:["hello", "world"]
- We now have a list containing two separate words
Step 2: Reverse each word individually
- Process first word:
"hello"[::-1]
โ"olleh"
- The slice
[::-1]
reads from the last character 'o' backwards to the first 'h'
- The slice
- Process second word:
"world"[::-1]
โ"dlrow"
- Similarly, 'd' is the last character and we read backwards to 'w'
- After reversing all words:
["olleh", "dlrow"]
Step 3: Join the reversed words with spaces
- Use
" ".join(["olleh", "dlrow"])
- Result:
"olleh dlrow"
The complete process transforms "hello world"
into "olleh dlrow"
, where each word has been reversed in place while maintaining the original word order and spacing structure.
For a more complex example with multiple spaces: if the input were "hello world"
(two spaces), split()
would still produce ["hello", "world"]
, and the final output would be "olleh dlrow"
with a single space, as split()
normalizes the spacing by default.
Solution Implementation
1class Solution:
2 def reverseWords(self, s: str) -> str:
3 """
4 Reverses each word in a string while maintaining word order.
5
6 Args:
7 s: Input string containing words separated by single spaces
8
9 Returns:
10 String with each word reversed but maintaining original word positions
11 """
12 # Split the string into individual words by spaces
13 # Reverse each word using slicing [::-1]
14 # Join the reversed words back together with single spaces
15 return " ".join(word[::-1] for word in s.split())
16
1class Solution {
2 /**
3 * Reverses each word in a string while maintaining the word order and spaces.
4 * For example: "Let's take LeetCode" becomes "s'teL ekat edoCteeL"
5 *
6 * @param s The input string containing words separated by single spaces
7 * @return A string with each word reversed but maintaining original word positions
8 */
9 public String reverseWords(String s) {
10 // Split the input string into an array of words using space as delimiter
11 String[] words = s.split(" ");
12
13 // Iterate through each word in the array
14 for (int i = 0; i < words.length; i++) {
15 // Reverse the current word using StringBuilder's reverse method
16 // and update it in the array
17 words[i] = new StringBuilder(words[i]).reverse().toString();
18 }
19
20 // Join all reversed words back together with single spaces
21 return String.join(" ", words);
22 }
23}
24
1class Solution {
2public:
3 string reverseWords(string s) {
4 // Create a stringstream to parse words from the input string
5 stringstream ss(s);
6
7 // Variable to store each word temporarily
8 string word;
9
10 // Variable to store the final result
11 string result;
12
13 // Extract words from the stringstream (automatically skips whitespace)
14 while (ss >> word) {
15 // Reverse the current word in-place
16 reverse(word.begin(), word.end());
17
18 // Append the reversed word to the result
19 result += word;
20
21 // Add a space separator after each word
22 result.push_back(' ');
23 }
24
25 // Remove the trailing space added after the last word
26 result.pop_back();
27
28 // Return the final string with all words reversed
29 return result;
30 }
31};
32
1/**
2 * Reverses the characters in each word of a string while maintaining word order and spaces
3 * @param s - The input string containing words separated by spaces
4 * @returns A new string with each word's characters reversed
5 */
6function reverseWords(s: string): string {
7 // Split the string into an array of words using space as delimiter
8 const words: string[] = s.split(' ');
9
10 // Reverse the characters in each word
11 const reversedWords: string[] = words.map((word: string) => {
12 // Convert word to character array, reverse it, then join back to string
13 return word.split('').reverse().join('');
14 });
15
16 // Join the reversed words back together with spaces
17 return reversedWords.join(' ');
18}
19
Time and Space Complexity
The time complexity is O(n)
, where n
is the length of the string s
. This is because:
s.split()
traverses the entire string once to split it into words:O(n)
- For each word
t
,t[::-1]
reverses it, which takes time proportional to the word's length - The total length of all words combined is at most
n
(excluding spaces), so reversing all words takesO(n)
in total " ".join()
combines the reversed words, traversing through all characters once:O(n)
- Overall:
O(n) + O(n) + O(n) = O(n)
The space complexity is O(n)
. This is because:
s.split()
creates a list of words that collectively contain up ton
characters:O(n)
- The list comprehension creates reversed versions of each word, requiring space for all reversed characters:
O(n)
" ".join()
creates a new string of length approximatelyn
:O(n)
- Overall:
O(n)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Handling Multiple or Irregular Spaces
The current solution using s.split()
without arguments treats multiple consecutive spaces as a single delimiter and removes them entirely. This means if the input has multiple spaces between words or leading/trailing spaces, they won't be preserved in the output.
Example where this fails:
- Input:
"Let's take LeetCode"
(multiple spaces between words) - Current output:
"s'teL ekat edoCteeL"
(single spaces) - Expected (if preserving spaces):
"s'teL ekat edoCteeL"
Solution:
If you need to preserve the exact spacing, use s.split(' ')
with a single space argument, but then handle empty strings:
def reverseWords(self, s: str) -> str:
words = s.split(' ')
return ' '.join(word[::-1] if word else '' for word in words)
Pitfall 2: Memory Usage with Large Strings
The current approach creates multiple intermediate strings (split list, reversed words, final joined string), which can be memory-intensive for very large inputs.
Solution: For memory-critical applications, consider an in-place approach using a list of characters:
def reverseWords(self, s: str) -> str:
chars = list(s)
start = 0
for end in range(len(chars) + 1):
if end == len(chars) or chars[end] == ' ':
# Reverse the word in place
left, right = start, end - 1
while left < right:
chars[left], chars[right] = chars[right], chars[left]
left += 1
right -= 1
start = end + 1
return ''.join(chars)
Pitfall 3: Unicode and Special Characters
The slice reversal [::-1]
works at the character level, which might produce incorrect results for certain Unicode combinations like emojis with modifiers or combining characters.
Example where this might fail:
- Input with emoji:
"Hello ๐จโ๐ฉโ๐งโ๐ฆ World"
(family emoji with zero-width joiners) - The reversal might break the emoji sequence
Solution: For proper Unicode handling, consider using libraries that understand grapheme clusters or implement proper Unicode-aware reversal.
Which algorithm is best for finding the shortest distance between two points in an unweighted graph?
Recommended Readings
Tech Interview Pattern Two Pointers Introduction If you prefer videos here's a super quick introduction to Two Pointers div class responsive iframe iframe src https www youtube com embed xZ4AfXHQ1VQ title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture allowfullscreen iframe div Two pointers is a common interview
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
Want a Structured Path to Master System Design Too? Donโt Miss This!