1451. Rearrange Words in a Sentence
Problem Description
You are given a sentence text
which is a string of space-separated words with the following properties:
- The first letter of the sentence is uppercase
- Words are separated by single spaces
Your task is to rearrange the words in the sentence based on their length in increasing order. If two or more words have the same length, they should maintain their original relative order from the input sentence.
After rearranging, the output should follow the same format as the input - the first letter should be uppercase and words should be separated by single spaces.
For example, if the input is "Leetcode is cool"
, the words have lengths [8, 2, 4]. After sorting by length while preserving the original order for same-length words, we get "is"
(length 2), "cool"
(length 4), "Leetcode"
(length 8). The final output would be "Is cool leetcode"
with the first letter capitalized.
The solution approach converts the first word to lowercase before sorting (to handle the capital letter uniformly), sorts all words by their length using a stable sort, then capitalizes the first letter of the result before joining the words back together with spaces.
Intuition
The main challenge in this problem is handling the capitalization requirement while sorting words by length. If we sort the words directly, the first word (which starts with a capital letter) might not end up in the correct position due to case sensitivity in string comparisons.
The key insight is that we need to normalize all words to the same case before sorting to ensure fair comparison. Since only the first letter of the sentence needs to be capitalized (not necessarily the first letter of the first word in the original sentence), we can:
- Convert the first word to lowercase to put all words on equal footing
- Sort the words purely by their length
- After sorting, capitalize the first letter of whatever word ends up first
Python's sort()
function is stable, meaning that when multiple elements have the same key (in this case, length), they maintain their original relative order. This naturally handles the requirement that words of the same length should appear in their original order.
The approach is elegant because it separates the concerns: first handle the sorting logic without worrying about capitalization, then apply the capitalization rule to the final result. This way, we avoid complex comparison functions or having to track which word was originally first.
Using key=len
in the sort operation directly compares words by their length, making the solution both readable and efficient.
Learn more about Sorting patterns.
Solution Approach
Let's walk through the implementation step by step:
-
Split the sentence into words: We use
text.split()
to break the sentence into a list of individual words. This automatically handles the single space separation. -
Normalize the first word: We convert the first word to lowercase using
words[0] = words[0].lower()
. This is crucial because the first word might have a capital letter that could affect its sorting position. By converting it to lowercase, we ensure all words are compared fairly by length alone. -
Sort words by length: We use
words.sort(key=len)
which sorts the list in-place. Thekey=len
parameter tells Python to use the length of each word as the sorting criterion. Since Python's sort is stable, words with the same length will maintain their original relative order from the input. -
Capitalize the new first word: After sorting, we apply the capitalization rule to whatever word is now at position 0 using
words[0] = words[0].title()
. Thetitle()
method capitalizes the first letter and lowercases the rest, which handles both cases where the new first word was originally lowercase or had mixed case. -
Join the words back: Finally, we use
" ".join(words)
to combine the sorted words back into a single string with spaces between them.
The time complexity is O(n log n)
due to the sorting operation, where n
is the number of words. The space complexity is O(n)
for storing the list of words.
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 the solution with the example "The quick brown fox"
:
Step 1: Split into words
- Input:
"The quick brown fox"
- After splitting:
["The", "quick", "brown", "fox"]
Step 2: Normalize the first word
- Convert "The" to lowercase:
["the", "quick", "brown", "fox"]
- This ensures the capital 'T' doesn't affect sorting
Step 3: Analyze word lengths
- "the": length 3
- "quick": length 5
- "brown": length 5
- "fox": length 3
Step 4: Sort by length (stable sort)
- Words of length 3: "the", "fox" (maintain original order)
- Words of length 5: "quick", "brown" (maintain original order)
- After sorting:
["the", "fox", "quick", "brown"]
Step 5: Capitalize the new first word
- Capitalize "the" β "The"
- Result:
["The", "fox", "quick", "brown"]
Step 6: Join with spaces
- Final output:
"The fox quick brown"
Notice how "the" and "fox" both have length 3, but "the" appears before "fox" in the final result because it came first in the original sentence. Similarly, "quick" and "brown" both have length 5 and maintain their original order.
Solution Implementation
1class Solution:
2 def arrangeWords(self, text: str) -> str:
3 # Split the text into individual words
4 words = text.split()
5
6 # Convert the first word to lowercase to ensure uniform sorting
7 # (since the original first word is capitalized)
8 words[0] = words[0].lower()
9
10 # Sort words by their length, maintaining relative order for words of same length
11 # Python's sort is stable, so original order is preserved for equal-length words
12 words.sort(key=len)
13
14 # Capitalize the first word of the rearranged sentence
15 words[0] = words[0].capitalize()
16
17 # Join the words back into a single string with spaces
18 return " ".join(words)
19
1class Solution {
2 public String arrangeWords(String text) {
3 // Split the input text into individual words
4 String[] words = text.split(" ");
5
6 // Convert the first word to lowercase to ensure consistent sorting
7 // (since the first word starts with uppercase in the original text)
8 words[0] = words[0].toLowerCase();
9
10 // Sort the words array by length in ascending order
11 // Words of the same length maintain their relative order (stable sort)
12 Arrays.sort(words, Comparator.comparingInt(String::length));
13
14 // Capitalize the first letter of the new first word
15 // to ensure the sentence starts with an uppercase letter
16 words[0] = words[0].substring(0, 1).toUpperCase() + words[0].substring(1);
17
18 // Join all words back together with spaces and return the result
19 return String.join(" ", words);
20 }
21}
22
1class Solution {
2public:
3 string arrangeWords(string text) {
4 // Parse the input text into individual words
5 vector<string> words;
6 stringstream stringStream(text);
7 string word;
8
9 // Extract each word from the text using stringstream
10 while (stringStream >> word) {
11 words.push_back(word);
12 }
13
14 // Convert the first character of the first word to lowercase
15 // This ensures all words are treated equally during sorting
16 words[0][0] = tolower(words[0][0]);
17
18 // Sort words by length while maintaining relative order of equal-length words
19 // stable_sort preserves the original order for words of the same length
20 stable_sort(words.begin(), words.end(),
21 [](const string& wordA, const string& wordB) {
22 return wordA.size() < wordB.size();
23 });
24
25 // Build the result string by concatenating sorted words
26 string result = "";
27 for (const auto& currentWord : words) {
28 result += currentWord + " ";
29 }
30
31 // Remove the trailing space added after the last word
32 result.pop_back();
33
34 // Capitalize the first character of the result to form a proper sentence
35 result[0] = toupper(result[0]);
36
37 return result;
38 }
39};
40
1/**
2 * Rearranges words in a sentence by their length in ascending order
3 * while maintaining the original order for words of the same length
4 * and ensuring proper sentence capitalization
5 *
6 * @param text - The input sentence to rearrange
7 * @returns The rearranged sentence with words sorted by length
8 */
9function arrangeWords(text: string): string {
10 // Split the input text into an array of words
11 const words: string[] = text.split(' ');
12
13 // Convert the first word to lowercase to ensure uniform sorting
14 words[0] = words[0].toLowerCase();
15
16 // Sort words by length in ascending order
17 // Note: JavaScript's sort is stable, preserving original order for equal lengths
18 words.sort((a: string, b: string) => a.length - b.length);
19
20 // Capitalize the first letter of the new first word to maintain sentence format
21 words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);
22
23 // Join the sorted words back into a sentence with spaces
24 return words.join(' ');
25}
26
Time and Space Complexity
Time Complexity: O(n log n)
- Splitting the text into words takes
O(n)
wheren
is the length of the input string - Converting the first word to lowercase takes
O(m)
wherem
is the length of the first word - Sorting the words by length takes
O(k log k)
wherek
is the number of words. In the worst case, if all words are single characters,k
could beO(n)
, making thisO(n log n)
- Converting the first word to title case takes
O(m)
wherem
is the length of the first word - Joining the words back together takes
O(n)
- Overall:
O(n) + O(m) + O(k log k) + O(m) + O(n)
=O(n log n)
(dominated by the sorting operation)
Space Complexity: O(n)
- The
words
list stores all words from the input text, requiringO(n)
space wheren
is the total length of the input string - The sorting operation may use additional
O(k)
space wherek
is the number of words (for the sorting algorithm's internal operations) - The final joined string also requires
O(n)
space - Overall:
O(n)
space complexity
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Handle the Original Capitalization
One of the most common mistakes is forgetting that the first word in the input is capitalized, which affects its sorting position. If you don't normalize it to lowercase before sorting, it might end up in the wrong position.
Incorrect approach:
def arrangeWords(self, text: str) -> str:
words = text.split()
words.sort(key=len) # Wrong! "Leetcode" will sort differently than "leetcode"
words[0] = words[0].capitalize()
return " ".join(words)
Why it fails: Capital letters have different ASCII values than lowercase letters. While this doesn't directly affect length-based sorting, the original capitalized word might have inconsistent casing when moved to a different position.
Solution: Always convert the first word to lowercase before sorting to ensure consistent comparison.
2. Using title()
Instead of capitalize()
While both methods can work, using title()
can cause issues if there are words with mixed cases or special characters.
Potential issue:
words[0] = words[0].title() # Can cause problems with words like "don't" β "Don'T"
Better approach:
words[0] = words[0].capitalize() # Safer: "don't" β "Don't"
3. Not Preserving Stable Order
Using a custom sorting function that doesn't maintain stability will break the requirement that same-length words maintain their original order.
Incorrect approach:
# Using a sorting method that isn't guaranteed to be stable
words = sorted(words, key=lambda x: (len(x), x)) # Wrong! This adds secondary sorting
Solution: Use Python's built-in sort()
or sorted()
with only the length as the key, as they guarantee stable sorting.
4. Modifying the Original Word Case
Some solutions might accidentally lowercase all words or fail to preserve the original casing of words (except the first one).
Incorrect approach:
def arrangeWords(self, text: str) -> str:
words = text.lower().split() # Wrong! This lowercases everything
words.sort(key=len)
words[0] = words[0].capitalize()
return " ".join(words)
Why it fails: If the input is "Leetcode is COOL", the output should preserve "COOL" as uppercase (except when it becomes the first word). The above approach would incorrectly change it to "cool".
A person thinks of a number between 1 and 1000. You may ask any number questions to them, provided that the question can be answered with either "yes" or "no".
What is the minimum number of questions you needed to ask so that you are guaranteed to know the number that the person is thinking?
Recommended Readings
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
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!