leetcode[541]翻转字符串里的单词/reverse words in a string 综合考察了字符串的多种操作

微信搜索「代码随想录」,更多精彩在等你!

思路

这道题目可以说是综合考察了字符串的多种操作。

那么问题来了,要不要使用split 和 reverse 等等库函数

这道题目中很多同学使用库函数走捷径解题,其实这也无可厚非,如果这样做,一定要确保自己可以实现这些库函数的功能,别看 split 好像很简单,其实很多时候自己去实现的时候错漏百出的。

解题思路:

  • 移除多余空格
  • 将整个字符串反转
  • 将每个单词反转

这样我们就完成了翻转字符串里的单词。

代码

效率:

class Solution {
public:
    // 反转字符串s中左闭又闭的区间[start, end]
    void reverse(string& s, int start, int end) {
        int offset = (end - start + 1) / 2;
        for (int i = start, j = end; i < start + offset; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    // 字符串去掉冗余的空格
    // 使用快慢指针发
    void removeExtraSpaces(string& s) {
        int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
        // 去掉字符串前面的空格
        while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
            fastIndex++;
        }
        for (; fastIndex < s.size(); fastIndex++) {
            // 去掉字符串中间部分的冗余空格
            if (fastIndex - 1 > 0
                    && s[fastIndex - 1] == s[fastIndex]
                    && s[fastIndex] == ' ') {
                continue;
            } else {
                s[slowIndex++] = s[fastIndex];
            }
        }
        if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') { // 去掉字符串末尾的空格
            s.resize(slowIndex - 1);
        } else {
            s.resize(slowIndex); // 重新设置字符串大小
        }
    }

    // 费时间的写法
    void removeExtraSpaces1(string& s) {
        for (int i = s.size() - 1; i > 0; i--) {
            if (s[i] == s[i - 1] && s[i] == ' ') {
                s.erase(s.begin() + i);
            }
        }
        // 删除字符串最后面的空格
        if (s.size() > 0 && s[s.size() - 1] == ' ') {
            s.erase(s.begin() + s.size() - 1);
        }
        // 删除字符串最前面的空格
        if (s.size() > 0 && s[0] == ' ') {
            s.erase(s.begin());
        }
    }

    string reverseWords(string s) {
        removeExtraSpaces(s); // 去掉冗余空格
        reverse(s, 0, s.size() - 1); // 将字符串全部反转
        int start = 0; // 反转的单词在字符串里起始位置
        int end = 0; // 反转的单词在字符串里终止位置
        bool entry = false; // 标记枚举字符串的过程中是否已经进入了单词区间
        for (int i = 0; i < s.size(); i++) { // 开始反转单词
            if ((!entry) || (s[i] != ' ' && s[i - 1] == ' ')) {
                start = i; // 确定单词起始位置
                entry = true; // 进入单词区间
            }
            // 单词后面有空格的情况,空格就是分词符
            if (entry && s[i] == ' ' && s[i - 1] != ' ') {
                end = i - 1; // 确定单词终止位置
                entry = false; // 结束单词区间
                reverse(s, start, end);
            }
            // 最后一个结尾单词之后没有空格的情况
            if (entry && (i == (s.size() - 1)) && s[i] != ' ' ) {
                end = i;// 确定单词终止位置
                entry = false; // 结束单词区间
                reverse(s, start, end);
            }
        }
        return s;
    }
};

笔者在先后在腾讯和百度从事技术研发多年,利用工作之余重刷leetcode,更多精彩文章,微信搜索「代码随想录」,本文 GitHub:https://github.com/youngyangyang04/leetcode-master 已经收录,欢迎star,fork,共同学习,一起进步。

猜你喜欢

转载自blog.csdn.net/youngyangyang04/article/details/107324307
今日推荐