Medium
题目描述
给你一个句子 text(句子是由空格分隔的单词组成的字符串),句子格式如下:
- 首字母大写
text中的每个单词都由单个空格分隔
你的任务是重新排列 text 中的单词,使所有单词按其长度的递增顺序重新排列。如果两个单词长度相同,则按它们在原句子中的顺序排列。
返回按上述格式重新排列的新文本。
示例 1:
输入:text = "Leetcode is cool"
输出:"Is cool leetcode"
解释:共有 3 个单词,"Leetcode" 长度为 8,"is" 长度为 2,"cool" 长度为 4。
输出按长度排序,新的第一个单词以大写字母开头。
示例 2:
输入:text = "Keep calm and code on"
输出:"On and keep calm code"
解释:输出按如下顺序排列:
"On" 2 个字母。
"and" 3 个字母。
"keep" 4 个字母,在长度相同的情况下按原文本中的位置排序。
"calm" 4 个字母。
"code" 4 个字母。
示例 3:
输入:text = "To be or not to be"
输出:"To be or to be not"
约束:
text以大写字母开头,然后包含小写字母和单词间的单个空格1 <= text.length <= 10^5
解题思路
这道题的核心思路是对单词进行稳定排序。我们需要:
- 分词处理:将输入的句子按空格分割成单词数组,同时记录每个单词的原始位置
- 大小写处理:将第一个单词转换为小写,因为排序后第一个位置可能会变化
- 稳定排序:按单词长度进行排序,长度相同时保持原有顺序(这是稳定排序的特性)
- 结果构建:将排序后的第一个单词首字母大写,然后用空格连接所有单词
关键点在于理解"稳定排序"的概念 - 当比较的元素相等时,它们的相对顺序不会改变。大多数编程语言的内置排序算法都是稳定的,这正好满足题目要求。
实现时有两种常见思路:
- 方法一:使用
(单词长度, 原始索引)作为排序键 - 方法二:直接利用稳定排序的特性,只按长度排序
推荐使用方法二,因为代码更简洁且性能更好。
代码实现
class Solution {
public:
string arrangeWords(string text) {
text[0] = tolower(text[0]);
vector<string> words;
stringstream ss(text);
string word;
while (ss >> word) {
words.push_back(word);
}
stable_sort(words.begin(), words.end(),
[](const string& a, const string& b) {
return a.length() < b.length();
});
if (!words.empty()) {
words[0][0] = toupper(words[0][0]);
}
string result;
for (int i = 0; i < words.size(); i++) {
if (i > 0) result += " ";
result += words[i];
}
return result;
}
};
class Solution:
def arrangeWords(self, text: str) -> str:
words = text.split()
words[0] = words[0].lower()
words.sort(key=len)
words[0] = words[0].capitalize()
return ' '.join(words)
public class Solution {
public string ArrangeWords(string text) {
string[] words = text.Split(' ');
words[0] = words[0].ToLower();
Array.Sort(words, (a, b) => a.Length.CompareTo(b.Length));
if (words.Length > 0) {
words[0] = char.ToUpper(words[0][0]) + words[0].Substring(1);
}
return string.Join(" ", words);
}
}
var arrangeWords = function(text) {
let words = text.split(' ');
words[0] = words[0].toLowerCase();
words.sort((a, b) => a.length - b.length);
words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);
return words.join(' ');
};
复杂度分析
| 复杂度 | 分析 |
|---|---|
| 时间复杂度 | O(n log n),其中 n 是单词的数量。主要消耗在排序操作上 |
| 空间复杂度 | O(m),其中 m 是字符串的总长度。需要存储分割后的单词数组 |