解法:原地翻转
思路:
第一步,将首部和中间多余空格移到字符串尾部。283.移动零
第二步,将字符串(不含尾部空格)原地翻转,先局部翻转,再整体翻转。
void swap(char *a, char *b)
{
char temp = *a;
*a = *b;
*b = temp;
}
char* reverseWords(char* s){
int total = strlen(s) + 1;
// step1.快慢指针将首部和中间多余空格移到后面去
int slow = 0, fast = 0;
while(slow < total && fast < total)
{
if(s[fast] != ' ' && s[fast] != '\0')
{
s[slow++] = s[fast++];
}
else
{
if(fast > 0 && s[fast-1] != ' ' ) s[slow++] = ' ';
fast++;
}
}
// 处理特殊情形:字符串全是空格
if(slow == 0) return "";
// step2. 局部翻转+整体翻转
int tail = slow-2; // 字符串非空时:确定尾部非空字符的位置
// 2.1 先翻转每个单词
int p = 0, q = 0;
for(int i=0; i<=tail; i++)
{
if(s[i] !=' ' && (s[i+1] == ' ' || s[i+1] == '\0'))
{
q = i;
while(p<q)
{
swap(&s[p++], &s[q--]);
}
p = i+2;
}
}
// 2.2 再翻转整个字符串,(不包括尾部空格)
p = 0, q=tail;
while(p<q)
{
swap(&s[p++], &s[q--]);
}
s[tail+1] = '\0';//不要忘了字符串尾部结束标志
return s;
}
时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)。