[LeetCode]45. Reverse Words in a String按单词翻转字符串

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

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

Update (2015-02-12):
For C programmers: Try to solve it in-place in O(1) space.

click to show clarification.

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.
 
解法1:使用C语言库函数strtok,先将字符串中的单词一个个截取暂存起来,然后反过来排列即可。使用额外的O(n)空间。
class Solution {
public:
    void reverseWords(string &s) {
        int n = s.size();
        vector<char*> word;
        char* c = new char[n + 1];
        strcpy(c, s.c_str());
        c[n] = '\0';
        char* delim = " ";
        char* wordp = nullptr;
        while ((wordp = strtok(c, delim)) != nullptr)
        {
            int m = strlen(wordp);
            char* tmp = new char[m + 1];
            strcpy(tmp, wordp);
            tmp[m] = '\0';
            word.push_back(tmp);
            c = nullptr;
        }
        s.clear();
        for (int i = word.size() - 1; i >= 0; --i)
            s += string(word[i]) + ' ';
        if(s.size() > 1) //注意去掉最后多加的那个空格
            s.resize(s.size() - 1);
    }
};

 

解法2:考虑先将整个字符串翻转过来,然后按单词再翻转过来,可以做到on-place。

class Solution {
public:
    void reverseWords(string &s) {
        int n = s.size(), k = 0;
        int left = 0, right = n - 1;
        while (left < right) //reverse the whole string
            swap(s[left++], s[right--]);
        for (int i = 0; i < n;) // reverse all words
        {
            while (i < n && s[i] == ' ') ++i;
            int j = i;
            while (i < n && s[i] != ' ') ++i;
            int m = i - 1;
            while (j < m)
                swap(s[j++], s[m--]);
        }
        for (int i = 0; i < n; ++i) //remove all spaces not necessary
        {
            bool flag = false;
            while (i < n && s[i] == ' ') ++i;
            while (i < n && s[i] != ' ')
            {
                s[k++] = s[i++];
                flag = true;
            }
            if(flag) s[k++] = ' ';
        }
        if (k > 0) s.resize(k - 1);
        if (k == 0) s.clear();
    }
};

或者先将每个单词翻转过来,然后整个字符串翻转。参考http://www.cnblogs.com/grandyang/p/4606676.html

class Solution {
public:
    void reverseWords(string &s) {
        int i = 0, j = 0, k = 0, wordCount = 0;
        while (true) {
            while (i < s.size() && s[i] == ' ') ++i;
            if (i == s.size()) break;
            if (wordCount) s[j++] = ' ';
            k = j;
            while (i < s.size() && s[i] != ' ') {
                s[j] = s[i];
                ++j; ++i;
            }
            reverseWord(s, k, j - 1);
            ++wordCount;
        }
        s.resize(j);
        reverseWord(s, 0, j - 1);
    }
    void reverseWord(string &s, int i, int j) {
        while (i < j) {
            char t = s[i];
            s[i++] = s[j];
            s[j--] = t;
        }
    }
};
posted @ 2015-10-28 10:30  AprilCheny  阅读(227)  评论(0编辑  收藏  举报