算法Week02.02 - LeetCode 151. Reverse Words in a String

来源:互联网 发布:windows phone 同步 编辑:程序博客网 时间:2024/05/17 06:05

题目大意

将给定的一个字符串出现的单词翻转顺序。

虽然题目给的要求很简单,不过还是有点小坑…因为题目说明完全没有体现出测试用例可能出现的情况…一开始还以为字符串都符合“单词+一个空格+单词+一个空格+…”的规范,如果是 SOJ 那种不带错误用例提示的,我这种死脑筋估计 de 半天也不会醒悟过来… orz

给定字符串的空白符可能是不规范的,字符串前后都可能有多余的空白符,单词之间也不一定只有一个空白符。

解题思路

因为是翻转问题,很容易就考虑到 LIFO 的数据结构 ——栈。

遍历字符串的字符,每次遇到非空白符则说明有一个单词(直到下一个空白符出现或者遇到字符串尾,说明单词的结束位置),获得单词的位置之后产生子串并 push 到栈中。

最后将栈中的所有单词按“单词+一个空格+单词+一个空格+…+单词”的规范合成字符串。

完整代码

#include <stack>using namespace std;class Solution {public:    void reverseWords(string &s) {        stack<string> str_stack;        int tmp;        for (int i = 0; i < s.size(); i++) {            if (s[i] != ' ') {                tmp = i;                for (i++; i < s.size(); i++) {                    if (s[i] == ' ') break;                }                str_stack.push(s.substr(tmp, i - tmp));            }        }        s = "";        while (!str_stack.empty()) {            if (!s.empty()) s += ' ';            s += str_stack.top();            str_stack.pop();        }    }};

思考

这题对 C Programmer 还有额外的要求:只使用 O(1) 的空间(不知道为什么对 C 有额外要求,难道 C 语言处理这个问题有特殊技巧?求小伙伴们告知)。

尝试了只用 O(1) 空间的解法,大致思路如下:
1. 消去字符串中多余的空格(移位操作);
2. 整体翻转字符串,比如“the sky is blue”-“eulb si yks eht”;
3. 整体翻转得到的单词虽然是逆序的,但它们占用的位置是正确的,这个时候只需要对每一个单词作翻转操作。

完整代码如下:

void reverseWords(char *s) {    if (!s) return;    bool ans;    int i, j, base;    char tmp;    // leave out redundant blanks    i = j = 0;    ans = false;    while (s[i]) {        if (s[i] != ' ') {            if (ans) {                s[j++] = ' ';                ans = false;            }            s[j++] = s[i++];        }        else {            i++;            if (j) ans = true;        }    }    s[j] = 0;    // reverse the whole string    i = 0;    while (i < j - i - 1) {        tmp = s[i];        s[i] = s[j - i - 1];        s[j - i - 1] = tmp;        i++;    }    // reverse words    i = j = base = 0;    while (s[i]) {        while (s[j] != ' ' && s[j]) j++;        while (i < j - (i - base) - 1) {            tmp = s[i];            s[i] = s[j - (i - base) - 1];            s[j - (i - base) - 1] = tmp;            i++;        }        if (!s[j]) break;        j++; i = base = j;    }}
0 0
原创粉丝点击