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

    题目描述:

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

    示例:  

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

    说明:

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

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

    要完成的函数:

    void reverseWords(string &s) 

    说明:

    1、这道题给定一个字符串s,相当于一个英文句子,要求把这个句子中的单词反转一下,后面的要放在前面,前面放在后面。

    这个句子中可能会有多余的空格,可能会出现在第一个字符前面,可能出现在单词之间,可能出现在最后一个字符后面。

    你要将多余的空格去掉,最前面和最后面不能有空格,单词之间的空格只能有一个。

    c或c++语言用户使用O(1)空间复杂度的原地解法,在字符串中修改,函数类型是void,不用返回。

    2、这道题如果允许多定义一个新字符串(长度与给定字符串相同),那么从给定字符串的后面读起,读出的字符从新的字符串的前面开始写起。

    在写的过程中,调整新字符串的空格,使之符合要求,最后调用resize函数修改新字符串的长度,这道题也就解决了。

    但现在要求原地解法,那么只能逐个交换了,后面跟前面交换,这样子换完之后,单词内部顺序也是反过来的,那再在单词内部交换一下,也就ok了。

    至于多余的空格问题,可以在交换之前,先解决掉这个问题,把后面的字符往前面移。

    笔者的代码思路如下,举个例子,字符串是   "(两个空格)the(三个空格)sky(两个空格)is(一个空格)blue(两个空格)":

    1、先反转整个字符串,变成(两个空格)eulb(一个空格)si(两个空格)yks(三个空格)eht(两个空格)。

    2、把后面的字符往前挪,去掉多余的空格,变成eulb(一个空格)si(一个空格)yks(一个空格)eht

    3、在单词内部进行反转,变成blue(一个空格)is(一个空格)sky(一个空格)the。

    所以具体代码如下:(附详解)

        void reverseWords(string &s) 
        {
            reverse(s.begin(),s.end());//先进行整个字符串的反转
            int i=0,j=0,start=0,t;
            while(i<s.size())//把字符往前挪,去掉多余的空格
            {
                while(i<s.size())//找到第一个非空格字符
                {
                    if(s[i]!=' ')
                        break;
                    i++;
                }
                if(i==s.size())break;//如果找不到非空格字符,此时已经i==s.size(),所以直接结束这一部分的任务
                j=i+1;
                while(j<=s.size())//找到i后面的第一个空格字符,位置记为j
                {
                    if(s[j]==' '||s[j]=='')
                        break;
                    j++;
                }
                while(i<j)//把i和j之间的字符往前挪,第一个就搬动到start这个位置,第二个搬动到start+1这个位置……
                {
                    s[start]=s[i];
                    start++;
                    i++;
                }
                s[start]=' ';//搬完一个单词之后,start现在这个位置变成空格字符
                start++;//start到空格的下一位,作为新的单词的起点
                i++;//i退出循环时,i==j,现在i++,变成空格的下一位,继续找下一个单词的起点
            }
            if(start==0)//边界条件,如果结束了上述任务之后,start还是为0,说明根本就没有非空格字符,那么s变成空字符串
    			s=s.substr(0,0);
    		else
    		{
    			s=s.substr(0,start-1);//去掉字符串后面多余的长度
    	        i=0,j=1;
    	        while(i<s.size())//把每一个单词反转过来
    	        {
    	        	while(j<=s.size())//找到空格位置,记为j
    		        {
    		        	if(s[j]==' '||s[j]=='')
    		        		break;
    		        	j++;
    				}
    				t=j+1;//记下来,作为下一个单词的起始位置
    				j--;
    				while(i<j)//单词内部反转
    				{
    					swap(s[i],s[j]);
    					i++;
    					j--;	
    				}
    				i=t,j=i+1;//更新i和j的位置
    			}   
    		}
            	

    上述代码实测4ms,beats 98.93% of cpp submissions。

  • 相关阅读:
    Java连接MongoDB样例
    Java Web项目BlogAutoGenerator编写日志1
    《算法竞赛入门经典》 第二章 循环结构程序设计 习题
    使用 Apache Tiles 3 构建页面布局
    Maven新建一个Spring MVC项目
    Maven手动添加dependency(以Oracle JDBC为例)
    一个简单的ServletContextListener示例
    《算法竞赛入门经典》学习笔记 2.4.4 C++中的输入输出
    《C++ Primer Plus》学习笔记 2.1.3 C++预处理器和iostream文件
    C# 温故而知新:Stream篇(—)
  • 原文地址:https://www.cnblogs.com/chenjx85/p/9613213.html
Copyright © 2011-2022 走看看