557. Reverse Words in a String III - Explanation
Description
Reverse the characters of every word in s. Keep the words in their original order and preserve the spaces separating them. Punctuation, digits, and other printable ASCII characters are part of their words.
Example 1:
Input: s = "a"
Output: "a"Explanation: Reversing a one-character word leaves it unchanged.
Example 2:
Input: s = "ab"
Output: "ba"Explanation: The word "ab" becomes "ba".
Example 3:
Input: s = "ab cd"
Output: "ba dc"Explanation: Reverse "ab" to "ba" and "cd" to "dc", keeping the words in their original order and preserving the space.
Constraints:
1 <= s.length <= 50000- All characters are printable ASCII. Words are separated by one space, with no leading or trailing spaces.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Two Pointers - Using pointers to identify word boundaries and reverse segments
- String Manipulation - Splitting strings and working with character arrays
- In-place Reversal - Swapping characters within a word without extra space
1. Convert To String Array
Intuition
The most straightforward approach splits the string into individual words, reverses each word separately, then joins them back together. By treating each word as an independent unit, we can use built-in string reversal methods on each one. This approach is simple to understand but requires extra space for the split words.
Algorithm
- Split the input string by spaces to get an array of words.
- For each word in the array, reverse its characters.
- Join the reversed words back together with spaces between them.
- Return the resulting string.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. String Manipulation
Intuition
Instead of splitting into an array, we can build the result string character by character. As we scan through the input, we accumulate characters for each word in reverse order by prepending each new character. When we hit a space, we append the reversed word to our result and reset for the next word. This avoids explicit array operations but involves string concatenation.
Algorithm
- Initialize an empty temporary string
tmp_strand an empty result stringres. - Iterate through each character in the input (plus one extra position to handle the last word).
- If we reach a space or the end of the string:
- Append
tmp_strtores, then cleartmp_str. - If not at the end, append a space to
res.
- Append
- Otherwise, prepend the current character to
tmp_str(building the word in reverse). - Return
res.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Two Pointers - I
Intuition
We can reverse each word in place by identifying word boundaries and using two pointers to swap characters within each word. As we scan through the string, we track where each word starts. When we encounter a space or reach the end, we know the word boundaries and can reverse that segment. This approach modifies a character array copy of the string directly.
Algorithm
- Convert the string to a character array.
- Use pointer
lto track the start of the current word. - Iterate with pointer
rthrough the array:- When
rreaches a space or the end of the string, we have found a complete word. - Use two temporary pointers to swap characters from both ends of this word toward the center.
- Update
ltor + 1for the next word.
- When
- Convert the character array back to a string and return.
class Solution:
def reverseWords(self, s: str) -> str:
s = list(s)
l = 0
for r in range(len(s)):
if s[r] == " " or r == len(s) - 1:
temp_l, temp_r = l, r - 1 if s[r] == " " else r
while temp_l < temp_r:
s[temp_l], s[temp_r] = s[temp_r], s[temp_l]
temp_l += 1
temp_r -= 1
l = r + 1
return "".join(s)Time & Space Complexity
- Time complexity:
- Space complexity:
4. Two Pointers - II
Intuition
This is a cleaner variation of the two-pointer approach. Instead of checking for word boundaries at every position, we explicitly find each word by scanning for non-space characters. Once we locate a word's start, we scan to find its end, reverse the word in place, then jump to the next word. This makes the logic more explicit and easier to follow.
Algorithm
- Convert the string to a character array.
- Iterate through the array with index
i:- Skip spaces until finding a non-space character (start of a word).
- From that position, use index
jto find where the word ends (next space or end of array). - Call a helper function to reverse characters between indices
iandj - 1. - Move
itojto continue with the next word.
- Return the modified array as a string.
class Solution:
def reverseWords(self, s: str) -> str:
def reverse(i, j):
while i < j:
s[i], s[j] = s[j], s[i]
i += 1
j -= 1
s = list(s)
i = 0
while i < len(s):
if s[i] != ' ':
j = i
while j < len(s) and s[j] != ' ':
j += 1
reverse(i, j - 1)
i = j + 1
return ''.join(s)Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Forgetting to Handle the Last Word
When iterating through the string looking for spaces to identify word boundaries, the last word has no trailing space. A common mistake is failing to reverse the final word because the loop only triggers reversal when encountering a space character.
Modifying Immutable Strings Directly
In languages where strings are immutable (like Python, Java, and JavaScript), attempting to modify the string in place will fail. You must first convert the string to a mutable data structure like a character array, perform the reversals, then convert back to a string.
Sign in to join the discussion