链接 151. 反转字符串中的单词 - 力扣(Leetcode)
题目
思路:
- 明确实现这个操作需要1.反转整个字符串 2.翻转单独的字母 3.删去多余的空格
昨天的原代码:写法有点混乱,变量太多,重复的步骤也多,导致错误很多也不好找
char * reverseWords(char * s){
int slen=strlen(s);
int len=slen;
int left=0;
//去除最前面的空格
while(s[left]==' ')
{
left++;
len--;
}
//去除最右边的空格
// int len=slen-1;
int right=len-1;
if(len<0)return NULL;//注意添加必要判断
while(s[right]==' ')
{
s[right]='\0';//涉及字符串的题目,记得要补充字符串结束语句
right--;
len--;
}
//去除字符串中多余的空格
int fast=left,slow=left;
while(fast<len)
{
if(s[fast]==' '&&s[fast+1]==' ')fast++;
else s[slow++]=s[fast++];
}
//反转整个字符串
int m=left;
int n=slow-1;
for(int i=left;i<slow;i++)
{
char temp=s[m];
s[m]=s[n];
s[n]=temp;
m++;
n--;
}
//翻转每个单词
for(int i=left;i<slow;i++)
{
int j=i;
while(j<slow&&s[j]!=' ')
{
j++;
}
int a=i;
int b=j-1;
for(int i=left;i<slow;i++)
{
char temp=s[a];
s[a]=s[b];
s[b]=temp;
a++;
b--;
}
i=j;//改变i的值,使其往这个单词后遍历
}
return s;
}
于是简化①:进行传参,实现字母翻转(翻转整个字符串及翻转单个单词的操作通过传参进行)
char*reverse(char*s,int start,int end)
{
int temp;
while(start<end)
{
temp=s[end];
s[end]=s[start];
s[start]=temp;
end--;
start++;
}
return s;
}
- 综合考虑,感觉先进行整个字符串的反转,然后进行单个单词的反转,最后进行多余空格的删除最易理解且简便
1.进行整个字符串的反转-->直接传参
// 1.整体反转字符串
int slen=strlen(s);
reverse(s,0,slen-1);
2.进行单个单词的反转:需要使用嵌套循环,固定一边端点i,另一边j往后遍历直至为空格,传参进行单词的翻转(注意,传入的末端需要j上-1)
int i=0;
while(i<slen)
{
int j=i;
while(j<slen)
{
if(s[j]!=' ')j++;
else break;
}
if(i!=j)reverse(s,i,j-1);//2
i=j+1;
}
此时选择这个顺序的好处显示出来:不许考虑两边的边界,即使左边界为空格也可以进行操作,只需要关注右边界字母和空格的分界
一开始的写法就是错在以为还需要考虑左边界
3.进行多余空格的删除
- 对首端空格的删除
int left=0;
// 删除字符串前端空格
while(slen>0&&s[left]==' ')
{
for(int i=0;i<slen;i++)
{
s[i]=s[i+1];
}
// left++;
slen--;
}
注意在这个步骤中左起点一直为0不变,不需要向右遍历 !!
- 对末端空格的删除
int right=slen-1;
// 删除字符串末端空格
while(slen>0&&s[right]==' ')
{
s[right]='\0';
right--;
slen--;
}
注意右端在缩短,故右边界不仅要进行给出字符串结束的操作,还要向左移动
- 对单词间多余空格的删除
// 删除单词中多余空格
int a=0;
while(a<slen)
{
if(s[a]==' '&&s[a+1]==' ')
{
for(int b=a;b<slen;b++)
{
s[b]=s[b+1];
}
slen--;
a--;//3
}
a++;
}
注意此操作中,slen减少后需进行a--,原因如下:
最终代码:
char*reverse(char*s,int start,int end)
{
int temp;
while(start<end)
{
temp=s[end];
s[end]=s[start];
s[start]=temp;
end--;
start++;
}
return s;
}
char * reverseWords(char * s){
// 1.整体反转字符串
int slen=strlen(s);
reverse(s,0,slen-1);
//2.翻转单个单词
int i=0;
while(i<slen)
{
int j=i;
while(j<slen)
{
if(s[j]!=' ')j++;
else break;
}
if(i!=j)reverse(s,i,j-1);//2
i=j+1;
}
// 3.删除多余空格
int left=0;
// 删除字符串前端空格
while(slen>0&&s[left]==' ')
{
for(int i=0;i<slen;i++)
{
s[i]=s[i+1];
}
// left++;
slen--;
}
int right=slen-1;
// 删除字符串末端空格
while(slen>0&&s[right]==' ')
{
s[right]='\0';
right--;
slen--;
}
// 删除单词中多余空格
int a=0;
while(a<slen)
{
if(s[a]==' '&&s[a+1]==' ')
{
for(int b=a;b<slen;b++)
{
s[b]=s[b+1];
}
slen--;
a--;//3
}
a++;
}
return s;
}
时间复杂度O(n)空间复杂度O(1)