题目来源:. - 力扣(LeetCode)
题目思路分析
题目要求我们将一个字符串中的单词顺序反转,但单词内部的字符顺序保持不变。例如,对于输入字符串 "Let's take LeetCode contest"
,输出应为 "contest LeetCode take Let's"
。
为了解决这个问题,我们可以分三步进行:
-
移除多余的空格:首先,我们需要去除字符串中的多余空格,包括字符串开头和结尾的空格,以及单词之间的多个空格。这可以通过遍历字符串并使用双指针技术来实现。
-
反转整个字符串:接下来,我们将整个字符串反转。这一步是为了将单词的顺序颠倒。
-
反转每个单词:最后,我们遍历反转后的字符串,找到每个单词的边界,并将每个单词再次反转回来,以恢复单词内部的字符顺序。
代码:
class Solution {
public:
// 辅助函数:反转字符串中的指定部分
void swapsome(string& s, int head, int tail) {
while (head < tail) {
swap(s[head], s[tail]);
++head;
--tail;
}
}
// 辅助函数:移除字符串中的多余空格
void removespace(string& s) {
int slow = 0; // 慢指针,指向处理后字符串的当前位置
for (int i = 0; i < s.size(); ++i) {
if (s[i] != ' ') {
// 如果慢指针不是初始位置,需要在慢指针位置添加一个空格
if (slow != 0) {
s[slow++] = ' ';
}
// 将非空格字符移动到慢指针位置,并移动快慢指针
while (i < s.size() && s[i] != ' ') {
s[slow++] = s[i++];
}
}
}
s.resize(slow); // 调整字符串大小,去除多余部分
}
// 主函数:反转字符串中的单词
string reverseWords(string s) {
removespace(s); // 第一步:移除多余空格
int start = 0; // 记录每个单词的起始位置
// 第二步:反转整个字符串
swapsome(s, start, s.size() - 1);
// 第三步:反转每个单词
for (int i = 0; i <= s.size(); ++i) {
if (i == s.size() || s[i] == ' ') {
swapsome(s, start, i - 1); // 反转当前单词
start = i + 1; // 更新下一个单词的起始位置
}
}
return s;
}
};
知识点摘要
- 字符串处理:使用双指针技术来遍历和修改字符串。
- 字符串反转:通过交换字符的位置来反转字符串的指定部分。
- 字符串大小调整:使用
std::string::resize
方法来调整字符串的大小。 - 空格处理:在处理字符串时,需要特别注意空格的去除和添加。
本文通过一个具体的字符串处理问题——反转字符串中的单词,展示了如何使用C++进行字符串处理。通过移除多余空格、反转整个字符串以及反转每个单词,我们成功地解决了这个问题。在解决问题的过程中,我们使用了双指针技术、字符串反转和字符串大小调整等关键知识点。这不仅提高了我们对字符串处理的理解,也为我们解决类似问题提供了思路和方法。希望这篇文章能帮助你更好地掌握字符串处理技巧,并在未来的编程实践中灵活运用。