题目: 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
示例:
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
1.利用辅助空间数组 O(N)S(N)
这个思想很简单,就是利用数组先把每个单词保存下来,在从尾到头放到字符串中,注意两点就可以了:
- 因为不能包含多余的空格,所以数组在保存单词是空格我们不进行保存,数组只存储单词
- 在从尾到头放到字符串时加空格,注意0号下标单词不加空格。
string reverseWords(string s)
{
vector<string> tmp;
string res="";
for(int i=0;i<=s.size();i++)
{
if(s[i]==' '|| s[i]=='\0')
{
if(res!="")//处理多余的空格
tmp.push_back(res);
res="";
}
else
{
res+=s[i];
continue;
}
}
for(int i=tmp.size()-1;i>=0;i--)
{
res=res+tmp[i];
if(i!=0)//为了防止末尾加空格
res+=" ";
}
return res;
}
int main()
{
string s="The sky";
cout<<reverseWords(s);
}
2.两次翻转字符串(麻烦)
建议如果需要处理空格的情况,用上面的比较好,好想一点,翻转字符串的话就需要处理太多了,主体思想就是先反转字符串,再反转每个单词。
- 先写一个反转函数
- 处理字符串,去掉前面的空格,后面的空格,单词之间的空格(快慢指针)
- 字符串反转
- 单词翻转。
string reverse(string s,int start,int end)//反转函数
{
char temp;
while(start<=end)
{
temp=s[start];
s[start]=s[end];
s[end]=temp;
start++;
end--;
}
return s;
}
string reverseWords(string s)
{
int start=0;
int end=s.size()-1;
string tmp="";
s.erase(0, s.find_first_not_of(' '));// 去掉前面的空格
s.erase(s.find_last_not_of(' ') + 1); // 去掉后面的空格
int fast = 1, slow = 0;//删掉单词间的多余空格
while (slow<s.length())
{
if (s[slow]==' '&& s[fast]==' ') // 当慢指针和快指针同时指向空字符时
{
// 如果有多于2的空字符,
// 就将快指针继续后移,一直到不是空字符为止
while (s[fast] == ' ')
{
fast++;
}
// 因为此时fast指向非空字符,
// 则删掉除slow指向的空字符外的其它空字符
// 删掉的空字符数为: fast - slow - 1
s.erase(slow, fast - slow - 1);
// slow指向空格,fast继续指向slow后面
fast = slow + 1;
} else {
slow++;
fast++;
}
}
end=s.size()-1;
s=reverse(s,start,end);//翻转了整个字符串
for(int i=0,j=0;i<=s.size(),j<=s.size();)
{
if(s[j]==' '||s[j]=='\0')
{
s=reverse(s,i,j-1);//饭庄单词
i=j+1;
j=i;
}
else
{
j++;
continue;
}
}
return s;
}
加油哦!💪。