给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:
输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明
- 无空格字符构成一个单词。
- 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
- 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
此题与剑指Offer第五十题类似,但比那个要难一点,因为题目要求删除多余空格,比那一题多一个要求。 思路应该比较清晰:
- 翻转整个句子
- 翻转句中单词
- 删除多余的空格
方法一:先去除首尾的空格,可利用trim函数。但是trim函数一直使用不成功。所以我用了比较笨的方法,先将原字符串开头空格去掉,利用s.substr(x),然后将整个字符串翻转,在删除开头的空格(也就是原尾部空格字符),然后再利用s.substr(y),将首尾的空格去除干净。然后再新建一个空字符串,用start和end记录单词的起始和截止位置,碰到连续空格跳过,传递给res,返回结果。
方法二:同方法一,思路更加清晰
方法三:字符流,用stringstream来做
O(n)
方法一:O(n)
方法二:O(1)
C++:
class Solution {
public:
void Reverse(string &s,int start,int end)
{
while(start < end)
{
swap(s[start],s[end]);
start++;
end--;
}
}
string reverseWords(string s)
{
string res;
int n = s.size();
int start=0,end=0;
int x=0,y=0;
while(x<n)
{
if (s[x]!=' ')
{
break;
}
x++;
}
s = s.substr(x);
end = s.size()-1;
// 整个句子翻转
Reverse(s,0,end);
while(y<s.size())
{
if (s[y]!=' ')
{
break;
}
y++;
}
s=s.substr(y);
int m = s.size();
int i=0;
while (i<m)
{
while(i<m && s[i]== ' ')
{
i++;
}
start = end = i;
while(i<m && s[i]!=' ')
{
i++;
end++;
}
Reverse(s,start,end-1);
for (int j=start;j<=end;j++)
{
res+=s[j];
}
}
return res;
}
};
class Solution {
public:
void Reverse(string &s,int start,int end)
{
while(start < end)
{
swap(s[start],s[end]);
start++;
end--;
}
}
string reverseWords(string s)
{
string res;
int n = s.size();
int start=0,end=0;
int x=0,y=n-1;
int count = 0;
while(x<n && y>=0)
{
if (s[x]==' ')
{
x++;
}
if (s[y]==' ')
{
y--;
count++;
}
if (s[x]!=' ' && s[y]!=' ')
{
break;
}
}
s = s.substr(x,n-count);
int m = s.size();
// 整个句子翻转
Reverse(s,0,m-1);
int i=0;
while (i<m)
{
while(i<m && s[i]== ' ')
{
i++;
}
start = end = i;
while(i<m && s[i]!=' ')
{
i++;
end++;
}
Reverse(s,start,end-1);
for (int j=start;j<=end;j++)
{
res+=s[j];
}
}
return res;
}
};
class Solution {
public:
void Reverse(string &s,int start,int end)
{
while(start<end)
{
swap(s[start++],s[end--]);
}
}
string cleanSpaces(string &s)
{
int n = s.size();
int i=0,j=0;
while(j<n)
{
while(j<n && s[j] == ' ') j++; // 跳过空格
while(j<n && s[j] != ' ')s[i++] = s[j++]; // 保留单词(非空格部分)
while(j<n && s[j] == ' ') j++; // 跳过空格(主要是防止结尾有空格,然后再添加空格越界)
if (j<n) s[i++] = ' '; // 补充空格
}
return s.substr(0,i);
}
string reverseWords(string s)
{
int n = s.size();
//翻转整个语句
Reverse(s,0,n-1);
// 翻转句中单词
int start = 0, end = 0;
int i=0;
while(i<n)
{
while(i<n && s[i]==' ') i++;
start = end = i;
while(i<n && s[i]!=' ')
{
i++;
end++;
}
Reverse(s,start,end-1);
}
//清除多余空格
s = cleanSpaces(s);
return s;
}
};
class Solution {
public:
string reverseWords(string s) {
stringstream ss;
string ans="",temp;
ss<<s;
while(ss>>temp){
ans=" "+temp+ans;
}
if(ans!="")
ans.erase(ans.begin());
return ans;
}
};
class Solution:
def reverseWords(self, s: str) -> str:
s = list(s)
n = len(s)
self.Reverse(s,0,n-1)
i =0
while i<n:
while i<n and s[i]==' ':
i+=1
start = end = i
while i<n and s[i]!= ' ':
i+=1
end+=1
self.Reverse(s,start,end-1)
s = self.cleanSpaces(s)
return s
def Reverse(self,s,start,end):
while start<end:
s[start],s[end] = s[end],s[start]
start+=1
end-=1
def cleanSpaces(self,s):
n = len(s)
i=0
j=0
while j<n:
while j<n and s[j]==' ':
j+=1
while j<n and s[j]!=' ':
s[i]=s[j]
i+=1
j+=1
while j<n and s[j]==' ':
j+=1
if j<n:
s[i] = ' '
i+=1
return "".join(s[:i])
class Solution:
def reverseWords(self, s: str) -> str:
return " ".join(s.split()[::-1])
## Python split() 通过指定分隔符对字符串进行切片,分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
## 字符串翻转的三种方法:1) [::-1]切片 2) 递归 3) 借用列表,使用reverse()方法 l=list(s) l.reverse() print("".join(l))