zoukankan      html  css  js  c++  java
  • LeetCode 151 翻转字符串里的单词

    题目:

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

    示例 1:

    输入: "the sky is blue"
    输出: "blue is sky the"
    

    示例 2:

    输入: "  hello world!  "
    输出: "world! hello"
    解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
    

    示例 3:

    输入: "a good   example"
    输出: "example good a"
    解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
    

    说明:

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

    进阶:

    请选用 C 语言的用户尝试使用 O(1) 额外空间复杂度的原地解法。

    解题思路:

    首先把字符串左右两边多余的空格给去掉,然后用两个指针分别从两段开始向中间扫描,将扫描到的左、右两个单词进行交换。这交换过程中注意下标的变换,因为两个单词长度不一定相等。

    代码:

     1 class Solution {
     2 public:
     3     string reverseWords(string s) {
     4         string temp;
     5         int l1,l2,r1,r2;
     6         l1=0,r2=s.size()-1;
     7   // 第一步:先把字符串两边的空格给去掉
     8         while(l1 <= r2) {   //1、这里取等于 可以处理 s=" "  这种特殊情况,即输出""
     9                 if(s[l1] == ' '){
    10                     s.erase(l1,1);
    11                     r2--;   //2、这里是r2改变,而不是l1,l1实际不需要改变
    12                 }
    13                 else
    14                     break;
    15     
    16             }
    17         while(l1 < r2 ) {
    18                 if(s[r2] == ' '){
    19                     s.erase(r2,1);
    20                     r2--;
    21                 }
    22                 else
    23                     break;
    24         }
    25   // 第二步:尺取左、右两个单词长度,然后交换两个单词,不断重复这个过程
    26         while(l1 < r2) 
    27         {
    28             temp.clear();
    29             for(r1=l1; r1<r2 && s[r1+1] != ' '; ++r1);   //3、找到两个单词边界
    30             for(l2=r2; l2>l1 && s[l2-1] != ' '; --l2);
    31             if(r1 >= l2)       //4、若只剩一个单词,则不必处理,直接退出
    32                break;
    33             int len1=r1-l1+1;
    34             int len2=r2-l2+1;
    35             temp = s.substr(l1, len1);
    36             s.erase(l1,len1);
    37             l2 = l2-len1;      //5、删除左边那个单词时,应该改变l2的值,但l1不用改变
    38             s.insert(l1,s.substr(l2,len2));
    39             l2 = l2+len2;     //6、插入之后l1,l2都要改变,因为l1要变为插入单词的下一个位置
    40             l1 = l1+len2;
    41             s.erase(l2,len2);
    42             s.insert(l2,temp);   //7、删除第l2位置开始的单词,再从该位置插入新单词。刚开始以为l2要减一,但其实insert(index,string)的用法是从index开始插入,而不是从index的后一个开始
    43             l2--;         //8、插入单词的前一个位置
    44             r2=l2;
    45  // 第三步:处理字符串内部多余空格
    46             int i,j;
    47             if(l1 >= r2)     //9、同4
    48                 break;
    49             else{
    50                 for(i=l1; i<r2 && s[i+1] == ' '; ++i);  //10、找出左右多余空格
    51                 for(j=r2; j>l1 && s[j-1] == ' '; --j);
    52                 if(i == j)    //11、若位置l1和r2之间已经没有多余的单词,并且只有一个空格,则保留这个空格并结束
    53                     break;
    54                 else if(i > j)  //12、若位置l1和r2之间已经没有多余的单词,但有多个空格,则删除多余的,只保留一个空格即可
    55                 {
    56                     s.erase(l1,i-l1);
    57                     r2=r2-(i-l1);
    58                     break;
    59                 }               
    60                                  //13、若位置l1和r2之间还有单词,则删除两边多余的空格
    61                 s.erase(l1,i-l1);
    62                 j=j-(i-l1);
    63                 r2=r2-(i-l1);
    64                 s.erase(j,r2-j);
    65                 r2=j-1;
    66                 l1++;
    67             }
    68 
    69         }
    70         return s;
    71     }
    72 };
  • 相关阅读:
    C++对象模型
    GUID 转 char *
    MFC中App,Doc,MainFrame,View各指针的互相获取
    MFC中设置某个VIEW为当前视图
    MFC中如何在CMainFrame类中访问CxxxView视图类中的成员
    GetMessage 和 PeekMessage 区别
    STL 常用容器
    收发ICMP封包,实现ping
    软件弹窗广告
    python 输入一个字符串,打印出它所有的组合
  • 原文地址:https://www.cnblogs.com/moxiangfeng/p/10664497.html
Copyright © 2011-2022 走看看