[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.
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; } } };