题目描述
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?
思路一:以空格为分隔符,将单词逐个提取并入栈;逐个出栈,并在单词之间加上空格,组成最后的字符串res,返回res即可
代码一:
class Solution {
public:
string ReverseSentence(string str) {
string res = "";
int len = str.size();
if(len == 0) return res;
stack<string> s;
string tmp = "";
for(int i = 0; i < len; ++i) {
if(str[i] != ' ') {
tmp += str[i];
} else {
s.push(tmp);
tmp = "";
}
}
s.push(tmp);
while(s.size() > 1) {
tmp = s.top();
s.pop();
res += tmp;
res += ' ';
}
res += s.top();
s.pop();
return res;
}
};
思路二: 使用双指针, 初始时left=0,right=0,每次扫描,将left指向单词头,将right指向单词结尾的后一个字符,并记录此单词的长度,并计算该单词应该插入res字符串的初始位置start,然后用一个for循环进行复制,更新left=right+1,right=left,并继续循环,时间复杂度为O(n),需要注意的是空格和字符串结束符对start、left、right的影响。
代码二:
class Solution {
public:
string ReverseSentence(string str) {
if(str.empty()) return "";
int len = str.size();
int left = 0;
int right = 0;
int lenWord;
int start = len;
int startTmp;
bool first = true;
string res = str;
while(right < len) {
while(str[right] != ' ' && right < len) ++right;
lenWord = right - left;
start -= lenWord;
startTmp = start;
--start;
for(int i = left; i < right; ++i)
res[startTmp++] = str[i];
if(first) {
first = false;
} else {
res[startTmp] = ' ';
}
left = right+1;
right = left;
}
return res;
}
};
思路三:定义子函数reverseStr()来对字符串进行反转操作,因此只需要先对整个字符串进行反转,然后依次对每个单词进行反转操作,即可得到最终答案。
代码三:
class Solution {
public:
string ReverseSentence(string str) {
if(str.empty()) return "";
int len = str.size();
reverseStr(str, 0, len - 1);
int left = 0;
int right = 0;
while(right < len) {
while(str[right] != ' ' && right < len) ++right;
reverseStr(str, left, right-1);
left = right+1;
right = right+1;
}
return str;
}
void reverseStr(string& str, int i, int j) { // j contain char of a word
int len = j - i + 1;
for(int k = 0; k < len/2; ++k) {
swapChar(str, i+k, j-k);
}
}
void swapChar(string& str, int i, int j) {
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
}
};