剑指offer44_翻转单词顺序列_题解

翻转单词顺序列

题目描述

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

示例1

输入

"nowcoder. a am I"

返回值

"I am a nowcoder."

分析

方案一:使用库函数

使用stringstream库函数将原始字符串转换成string的字符串数组,然后逆序拼接成新的字符串。

代码

/**
1.时间复杂度:O(n)
2.空间复杂度:O(n)
**/
class Solution
{
public:
    string ReverseSentence(string str)
    {
        //判空
        if (str.empty())
            return str;

        //跳过开头的空格使得i指向第一个非空格字符
        int i = 0, n = str.size();
        while (i < n && str[i] == ' ')
            i++;

        //如果字符串全为空格则返回源字符串
        if (i == n)
            return str;

        //拆分单词
        stringstream iss(str);
        vector<string> ret;
        string s;
        while (iss >> s)
            ret.emplace_back(s);

        //合并字符串
        stringstream oss;
        for (int i = ret.size(); i >= 1; --i)
            oss << ret[i] << ' ';
        oss << ret[0];

        return oss.str();
    }
};

方案二:双指针

先翻转整个字符串,再对每个单词翻转

代码

/**
1.时间复杂度:O(n)
2.空间复杂度:O(n)
**/
class Solution
{
public:
    string ReverseSentence(string s)
    {
        //翻转整个句子
        reverse(s.begin(), s.end());
        //翻转句子中的每个单词
        int i = 0, j = 0, n = s.length(); //i指向单词第一个字母,j指向单词最后一个字母的下一个字母
        while (i < n)
        {
            //如果i指向的第一个字母是空格,则i++,j++
            //保证i指向的是单词第一个字母
            if (s[i] == ' ')
            {
                i++;
                j++;
            }
            // 情况1:j刚刚越过数组最后一个角标
            // 情况2:尾部是空格
            // 遇到这两种情况就进行单词的翻转,并更新i的下标
            else if (j == n || s[j] == ' ')
            {
                reverse(s.begin() + i, s.begin() + j);
                i = ++j;
            }
            //i和j指向的都不是空格,说明j还没有遍历到单词的末尾,j++即可
            else
            {
                j++;
            }
        }
        return s;
    }
};
posted @ 2021-01-16 20:55  RiverCold  阅读(68)  评论(0编辑  收藏  举报