剑指 Offer 58 - I. 翻转单词顺序
题目链接:
题目描述
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串”I am a student. “,则输出”student. a am I”。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
思路分析
思路一
1.反序字符串 hello world-》dlrow olleh
2.再对每个单词进行正序 dlrow olleh -》world hello
说明:以上步骤仅对 首尾无多余空格,相邻单词仅一个空格输入有效, 对于多出来的空格代码里有具体解决方案
待补充
代码结构设计
1.整个句子的首尾标记,交换后向中间靠拢直到相遇
2.单词的首位标记,初始 Wbeg Wend指向dlrow的d,Wbeg向后遍历
遇到普通字符,Wbeg++
遇到空格,确定单词范围(Wend,Wbeg-1),对范围单词反向;Wbeg=Wbeg+1,Wend=Wbeg.移到下单词
或者遇到’ ’,确定单词范围(Wend,Wbeg-1),对范围单词反向;结束
代码具体实现
- class Solution {
- public:
- //由于反序整个字符串和整个单词用的用同一个功能所以提取出公共函数
- void Reverse(string &s, int start, int end) {
- while(start < end) {
- char tmp = s[start];
- s[start++] = s[end];
- s[end--] = tmp;
- }
- }
- string reverseWords(string s) {
- Reverse(s, 0, s.length()-1); // 1
- // 2
- int Wbeg = 0, Wend = 0;
- while(1) {
- if(s[Wbeg] == ' ') {
- Reverse(s, Wend, Wbeg-1);
- Wbeg++;
- Wend = Wbeg;
- }else if(s[Wbeg] == ' ') {
- Reverse(s, Wend, Wbeg-1);
- break;
- }else {
- Wbeg++;
- }
- }
- //之后是对题目描述中说明的多余空格的处理
- //去除空格,多余空格 首尾空格 俩单词间仅一个空格
- istringstream ss(s);
- string tmp_str, result;
- while(ss >> tmp_str) {
- result += tmp_str;
- result += " ";
- }
- //最后多一个空格所以就删去最后一位 前移
- if(result != "")//对于为空的字符串就什么也不做
- result[result.length() - 1] = ' ';
- return result;
- }
- };