剑指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;
}
};