LeetCode151. 翻转字符串里的单词

题目

给定一个字符串,逐个翻转字符串中的每个单词。

说明:

无空格字符构成一个 单词 。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

代码

一、 从后往前找到找到单词加入新字符串

 1 class Solution {
 2 public:
 3     string reverseWords(string s) {
 4         string res ;
 5         int j = s.length()-1;
 6         while(j >= 0){
 7             if(s[j] == ' '){
 8                 j--;
 9                 continue;
10             }
11             
12             while(j >= 0 && s[j] != ' '){
13                 j--;
14             }
15             int tmp = j;  //保存单词前的空格位置,后移为单词的起始位置
16             j++;
17             while(j < s.length() && s[j] != ' '){
18                 res += s[j];
19                 j++;
20             }
21             j = tmp;
22             res += ' '; 
23         }
24         if(*(res.end() -1)  == ' ') res.erase(res.end()-1);
25         return res;
26     }
27 };

二、按照Carl提高下该题的难度,就是使用就地算法,不开辟新的字符串,怎样实现

1.去除多余空格

2.整体字符串反转

3.单词再反转

首先移除多余空格,不要上来直接用erase删除,因为最快的删除字符串的元素的时间复杂度也是O(n),再在外部套一层循环,实际时间复杂度为方。如何将降低?双指针。

 1 class Solution {
 2 public:
 3     //整个移除元素操作借鉴数组移除元素那道题,用快慢指针实现
 4     //移除空格相当于将整个数组向前覆盖
 5     void removeExtraSpaces(string &s){
 6         int fast = 0, slow = 0;  //定义快慢指针,快指针在有效单词位置
 7         //首先移除字符串单词前面空格
 8         //先找到首个单词开头的位置
 9         while(fast < s.length() && s[fast] == ' '){
10             fast++;
11         }
12         //若开头有冗余空格,利用双指针将整体字符串前移
13         //并且去除字符串中间部分的冗余空格---逻辑和27题一样
14         for(;fast < s.length();fast++){
15             if(fast > 0 && s[fast] == s[fast - 1] && s[fast] == ' '){
16                 continue;
17             }else{
18                 s[slow++] = s[fast];
19             }
20         }
21         //此时slow指针指向了最后一个单词的有效字符的后一个位置
22         //去除末尾的冗余空格,用resize,slow之后都为冗余字符
23         if(slow > 0 && s[slow - 1] == ' ') s.resize(slow - 1);
24         else s.resize(slow);
25     }
26     //常见的数组逆序操作,也是双指针
27     void reverse(string &s,int start,int end){
28         for(int i = start,j = end;i < j;i++,j--){
29             swap(s[i],s[j]);
30         }
31     }
32     
33     string reverseWords(string s) {
34         removeExtraSpaces(s);
35         reverse(s,0,s.length()-1);
36         //反转单词
37         int i = 0;
38         bool flag = false;
39         for(int k = 0; k < s.length();k++){
40             if((!flag )  && (s[k] != ' ' )  ){
41                 i = k;
42                 flag = true;
43             }
44             if(((k > 0 ) && (s[k] == ' ' )&& (s[k-1] != ' ') &&(flag))){
45                 reverse(s,i,k-1);
46                 i = k+1;
47                 flag = false;
48             }
49             
50         }
51         reverse(s,i,s.length()-1);
52 
53         //时间复杂度为n方的写法
54         // while(j < s.length() && s[j] != ' '){
55         //     j++;
56         // }
57 
58         // while(j < s.length()){
59         //     while(j < s.length() && s[j] != ' '){
60         //         j++;
61         //     }
62         //     reverse(s,i,j -1);
63         //     i = ++j;
64             
65         // }
66         return s;
67     }
68 };

注意最后挑选单词进行反转

原文地址:https://www.cnblogs.com/fresh-coder/p/14319619.html