剑指offer59_翻转单词顺序
翻转单词顺序
输入一个英文句子,单词之间用一个空格隔开,且句首和句尾没有多余空格。
翻转句子中单词的顺序,但单词内字符的顺序不变。
为简单起见,标点符号和普通字母一样处理。
例如输入字符串"I am a student."
,则输出"student. a am I"
。
数据范围
输入字符串长度 [0,1000]。
样例
输入:"I am a student."输出:"student. a am I"
算法思路
- 首先反转整个字符串
- 然后逐个识别单词并再次反转每个单词
- 通过双指针法(i和j)定位每个单词的起始和结束位置
- 时间复杂度: O(n)
- 第一次整体反转:O(n)
- 单词识别和反转:O(n)(每个字符最多被访问两次)
- 空间复杂度: O(1)
- 原地操作,没有使用额外空间(除了几个临时变量)
class Solution {
public:string reverseWords(string s) {// 第一步:反转整个字符串reverse(s.begin(), s.end());// 第二步:逐个识别并反转每个单词for(int i = 0; i < s.size(); i ++){if(s[i] == ' ') continue; // 跳过空格// 定位单词结束位置(下一个空格或字符串结尾)int j = i + 1;while(j < s.size() && s[j] != ' ') j++;// 反转当前单词reverse(s.begin() + i, s.begin() + j);i = j; // 跳过已处理的单词}return s;}
};
实例演示
示例1:输入 “hello world”
- 整体反转:
"dlrow olleh"
- 反转单词:
- 第一个单词 “dlrow” → “world”
- 第二个单词 “olleh” → “hello”
- 最终结果:
"world hello"
示例2:输入 “the sky is blue”
- 整体反转:
"eulb si yks eht"
- 反转单词:
- “eulb” → “blue”
- “si” → “is”
- “yks” → “sky”
- “eht” → “the”
- 最终结果:
"blue is sky the"
示例3:输入 " a good example "
- 整体反转:
" elpmaxe doog a "
- 反转单词:
- “elpmaxe” → “example”
- “doog” → “good”
- “a” → “a”
- 最终结果:
"example good a"
(注意空格被保留在原位)
边界情况处理
- 前导/后置空格:保留在原位
- 连续多个空格:保留原样
- 单个单词:效果等同于字符串反转
- 空字符串:直接返回