1. 程式人生 > >leetcode151-Reverse Words in a String(翻轉字串單詞的位置)

leetcode151-Reverse Words in a String(翻轉字串單詞的位置)

1、問題描述:

Given an input string, reverse the string word by word.

For example,

Given s = "the sky is blue",
return "blue is sky the".

Clarification:

What constitutes a word?
A sequence of non-space characters constitutes a word.
一串非空字元組成單詞

Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
輸入字串的首尾都可能包含空格,但是翻轉後的字串不要有

How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
應該處理兩單詞間連續多個空格的情況,使其只包含一個

2、問題求解:

方法一:O(n)時間,並且需要輔助空間O(n)

class Solution {
public:
    void reverseWords(string &s) {//如s為“the sky”
        int n=s.size();
        int i=n-1;
        //輔助字串存放結果字串
string stmp="";//最後為“sky the” while(i >= 0) { while(s[i]==' ' && i>=0) {//(1)處理連續有多個空格的情況 i--; } if(i<0) break;//s處理完空格,若後續沒有單詞則應跳出迴圈 string wordtmp=""; for(;i>=0 && s[i]!=' '
;i--) {//(2)從後往前遍歷,每次取得一個單詞賦給wordtmp wordtmp += s[i]; }//第一個單詞為yks //(3)翻轉wordtmp,如yks reverse(wordtmp.begin(), wordtmp.end()); if(stmp != "") {//(4)在將翻轉後的單詞加入到stmp之前先加入空格(若非首單詞) stmp.append(" "); } stmp.append(wordtmp);//(5)加入到stmp } s=stmp; } };

方法二:O(n)時間,不需要輔助空間

(1)從前往後遍歷,依次翻轉每個單詞
(2)翻轉整個字串

class Solution {
public:
    void reverseWords(string &s) {
        int n=s.size();
        int i=0, j=0;
        int start=0;
        while(i<n)
        {
            while(i<n && s[i]==' ') i++;//(1)處理空格
            if(i<n && j>0)
            {//(2)如果處理到非首單詞(j>0),要在其前加入空格
                s[j++]=' ';
            }
            //(3)翻轉每個單詞
            start=j;
            while(i<n && s[i]!=' ')
            {
                s[j++]=s[i++];
            }
            reverse(s.begin()+start, s.begin()+j);
        }
        s.resize(j);//(4)重置s大小
        reverse(s.begin(), s.end());//(5)翻轉整個字串
    }
};

3、擴充套件:

對於一個給定的字串,我們需要線上性(也就是O(n))的時間裡對它做一些變形。首先這個字串中包含著一些空格,就像”Hello World”一樣,然後我們要做的是把著個字串中由空格隔開的單詞反序,同時反轉每個字元的大小寫。比如”Hello World”變形後就變成了”wORLD hELLO”。

分析:該題與上題的區別是不丟棄字串前後的空格,只不過翻轉後後邊的空格放到前面,而前面的空格放到後面;再就是單詞大小寫轉換。

#include <iostream>
#include<string.h>
#include<algorithm>
using namespace std;

class Transform {
public:
    string trans(string s, int n) {
        int i=n-1;
        //輔助字串存放結果字串
        string stmp="";//最後為“sky the”
        while(i >= 0)
        {//從後往前
            while(s[i]==' ' && i>=0)
            {//(1)見到空格就放入stmp(後面的空格最終放到前面,單詞之間的空格也會放入)
                stmp.append(" ");//!!!
                i--;
            }
            //if(i<0) break;//s處理完空格,若後續沒有單詞則應跳出迴圈
            string wordtmp="";
            for(;i>=0 && s[i]!=' ';i--)
            {//(2)從後往前遍歷,每次取得一個單詞賦給wordtmp
                wordtmp += s[i];
            }//第一個單詞為yks
            //(3)翻轉wordtmp,如yks
            reverse(wordtmp.begin(), wordtmp.end());
            /*
            if(stmp.find_first_not_of(" ")!=string::npos || stmp!="")
            {//(4)在將翻轉後的單詞加入到stmp之前先加入空格(若非首單詞)
                stmp.append(" ");
            }*/
            stmp.append(wordtmp);//(5)加入到stmp
        }
        s=stmp;
        cout<<s<<" "<<s.size()<<endl;
        //(4)下邊用於轉換大小寫
        i=0;
        while(i<n)
        {
            if(s[i]==' ') i++;
            else
            {
                s[i]=isupper(s[i])?tolower(s[i]):toupper(s[i]);
                i++;
            }
        }
        return s;
    }
};

int main()
{
    Transform t;
    string str="  We are champion";
    //string str1=" h i";
    int n=str.size();
    cout<<n<<endl;
    string res=t.trans(str, n);
    cout<<res<<endl;
    return 0;
}

結果:

17
champion are We   17
CHAMPION ARE wE

Process returned 0 (0x0)   execution time : 2.889 s
Press any key to continue.

即翻轉後字串大小不變。

若輸入"  We are champion",則輸出"CHAMPION ARE wE  ".