在 C++ 中,字符串处理是常见的面试与算法练习题。本题目标是:反转字符串中每个单词的字符顺序,但保持单词顺序不变。
示例:
输入: "Hello World"
输出: "olleH dlroW"
也就是说:
Hello → olleH
World → dlroW
下面介绍 两种经典实现方法。
一、方法一:使用字符串流(stringstream)
利用 将字符串按单词拆分,然后逐个反转。
思路
- 使用
stringstream按空格分割单词 - 使用
reverse()反转单词 - 拼接结果字符串
代码实现
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
string reverseWords(string s) {
stringstream ss(s);
string word;
string result;
while (ss >> word) {
reverse(word.begin(), word.end());
result += word + " ";
}
result.pop_back();
return result;
}
int main() {
string str = "Hello World";
cout << reverseWords(str) << endl;
return 0;
}
输出:
olleH dlroW
时间复杂度
O(n)
空间复杂度:
O(n)
优点:
- 代码简单
- 可读性好
缺点:
- 使用额外空间
二、方法二:双指针原地反转
使用 双指针扫描字符串,找到每个单词的范围并进行反转。
思路
- 遍历字符串
- 找到单词起始位置
- 找到单词结束位置
- 调用
reverse()反转
代码实现
#include <iostream>
#include <algorithm>
using namespace std;
string reverseWords(string s) {
int start = 0;
for (int i = 0; i <= s.size(); i++) {
if (i == s.size() || s[i] == ' ') {
reverse(s.begin() + start, s.begin() + i);
start = i + 1;
}
}
return s;
}
int main() {
string str = "Hello World";
cout << reverseWords(str) << endl;
return 0;
}
输出:
olleH dlroW
时间复杂度
O(n)
空间复杂度:
O(1)
优点:
- 原地操作
- 更节省内存
缺点:
- 实现稍复杂
三、两种方法对比
| 方法 | 思路 | 空间复杂度 | 适合场景 |
|---|---|---|---|
| stringstream | 拆分单词再反转 | O(n) | 简单实现 |
| 双指针 | 原地扫描 | O(1) | 面试优化 |
四、进阶问题(面试常问)
很多面试会继续延伸:
1 反转单词顺序
例如:
"Hello World"
→ "World Hello"
2 去除多余空格
例如:
" hello world "
→ "world hello"
3 整个字符串反转 + 单词反转
经典算法:
1 先整体反转
2 再逐个单词反转
该题在很多算法平台都有类似题目,例如:
- LeetCode
五、总结
反转字符串中单词字符顺序的核心方法:
1️⃣ 使用 字符串流分割单词
2️⃣ 使用 双指针原地反转
关键函数:
reverse()
来自:
如果你愿意,我可以继续给你整理一份 C++字符串算法经典 20 题(面试高频),包括:
- 反转字符串
- 最长回文子串
- 字符串压缩
- KMP 字符串匹配算法。