zoukankan      html  css  js  c++  java
  • 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 };

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

  • 相关阅读:
    Confluence 6 连接到一个 LDAP 目录
    Confluence 6 LDAP 成员结构设置
    Confluence 6 LDAP 用户组结构设置
    Confluence 6 LDAP 用户结构设置
    Confluence 6 LDAP 高级设置
    Confluence 6 自动添加用户到用户组
    Confluence 6 权限设置
    一个小白的测试环境docker化之路
    客户端SDK测试思路
    限时购校验小工具&dubbo异步调用实现限
  • 原文地址:https://www.cnblogs.com/fresh-coder/p/14319619.html
Copyright © 2011-2022 走看看