给你一个字符串 s ,请你反转字符串中单词的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue"
输出:"blue is sky the"
示例 2:
输入:s = " hello world "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = "a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
方法一:自行编写函数:
首先翻转整个字符串,再对每个单词内部进行翻转,完成字符串内的单词翻转。
时间复杂度:O(n),空间复杂度:O(1)。
用到了reverse()函数。
class Solution{
public:
string reverseWords(string s){
//翻转整个字符串
/*void reverse(BidirectionalIterator first,BidirectionalIterator last)
bidirectional iterator 双向迭代器,将[first, last)范围内的元素颠倒顺序放置*/
reverse(s.begin(),s.end());
int n = s.size();
int idx = 0;
for(int start=0;start<n;++start){
if(s[start]!=' '){
//填一个空白字符然后将idx移动到下一个单词的开头位置(单词间隔)
if(idx != 0)s[idx++]=' ';
//循环遍历整个单词
int end=start;
while(end<n && s[end]!=' ') s[idx++]=s[end++];
//翻转整个单词
reverse(s.begin()+idx-(end-start),s.begin()+idx);
//更新start到下一个单词
start=end;
}
}
s.erase(s.begin()+idx,s.end());//擦掉末尾部分的空白
return s;
}
};
方法二:双端队列:
由于双端队列支持从队列头部插入的方法,因此我们可以沿着字符串一个一个单词处理,然后将单词压入队列的头部,再将队列转成字符串即可。
时间复杂度:O(n),n为输入字符串的长度。
空间复杂度:O(n),双端队列存储单词需要O(n)的空间。
class Solution{
public:
string reverseWords(string s){
int left=0;right=s.size()-1;
//去掉开头的空白字符
while(left<=right && s[left]==' ') ++left;
//去掉末尾的空白字符
while(left<=right && s[right]==' ') --right;
deque<string> d;
string word;
while(left<=right){
char c=s[left];
if(word.size() && c==' '){
//将单词push到队列的头部
d.push_front(move(word));
word="";
}
else if(c!=' '){
word+=c;
}
++left;
}
d.push_front(move(word));
string ans;
while(!d.empty()){
ans += d.front();
d.pop_front();
if(!d.empty()) ans += ' ';
}
return ans;
}
};
标签:空格,string,队列,单词,字符串,翻转 From: https://www.cnblogs.com/chordxx/p/17369746.html