344.反转字符串
思路:双指针法,一个在头一个在尾,交换后同时往中间走
void reverseString(char* s, int sSize){
int left=0,right=sSize-1;
while(left<right){
char t = s[left];
s[left] = s[right];
s[right] = t;
left++;
right--;
}
}
541.反转字符串II
思路:
i 初始为 0,i 每次走 2k 步,当剩余位(strlen(s) - i)> || = k 时,翻转前 k 位;当剩余位数 < k 时,剩余位全部翻转;
注意:
翻转函数右区间要 - 1;
每次反转的时候,i 是从当前位置 s[i] 开始翻转的,不是走过 2k 个才反转;
void reverseString(char *s , int a , int b){
b--;
while(a<b){
int t=s[a];
s[a]=s[b];
s[b]=t;
a++;
b--;
}
}
char * reverseStr(char * s, int k){
for(int i=0;i<strlen(s);i+=2*k){
if(i+k<strlen(s)){
reverseString(s,i,i+k);
}
else
{
reverseString(s,i,strlen(s));
}
}
return s;
}
剑指 Offer 05. 替换空格
思路:
找出空格数,请求一块新的空间存新字符串,定义两个指针:i 指向原字符串尾,j 指向新字符串尾,当遇到非空格元素时,存入新字符串 ;遇到空格时,将字符 ’0‘、’2‘、’%‘ 全部存入新字符串。
注意:
开辟新空间时,要为 '\0' 也申请一块;
最后要给新字符串尾加上 ’\0‘;
类似填充的问题,都可以先把数组扩容然后从后向前操作
char* replaceSpace(char* s){
int count=0;
for(int i=0;i<strlen(s);i++){
if(s[i]==' '){
count++;
}
}
int newlen=strlen(s) + count*2;
char *result=malloc(sizeof(char)*newlen+1);
for(int i = strlen(s)-1 , j = newlen-1 ; i>-1 ; i--){
if(s[i] != ' ')
result[j--]=s[i];
else
{
result[j--] = '0';
result[j--] = '2';
result[j--] = '%';
}
}
result[newlen]='\0';
return result;
}
151.反转字符串中的单词
思路:
1.去除空格:先去掉字母之前的空格( fast 指针遇到空格就往前走,直到遇到字母,这时,直接赋值给 s[slow]),再去中间部分( fast 遇到空格时,若前一个也是空格, fast 往前走),最后去掉结尾的空格(如果有空格:此时 slow 指向一个空格,slow 的前一个位置也是一个空格,这时要将将前一个位置 slow - 1赋值为 ’\0’;如果结尾没有空格:将这时 slow 的位置赋值为 ’\0'
2.反转整个字符串
3.反转其中的单词
注意:数组溢出:slow - 1, slow = 0 时,数组可能溢出;
void Reverse_Word(char *s,int a,int b){
while(a < b){
int t = s[a];
s[a] = s[b];
s[b] = t;
a++;
b--;
}
}
char * reverseWords(char * s){
int slow=0,fast=0;
while(s[fast] == ' ' && fast < strlen(s)){
fast++;
}
//去除字符串前的空格;
for(;fast < strlen(s);fast++){
if(fast-1>0 && s[fast-1] == s[fast] && s[fast] == ' ')
{
continue;
}
else
{
s[slow++] = s[fast];
}
}
//去除中间空格
if(slow-1>0 && s[slow-1] == ' ')
s[slow-1] = '\0';
else
s[slow]='\0';
//去除末尾空格
Reverse_Word(s, 0,strlen(s)-1);
//反转整个字符串
int i,j;
for( i = 0,j = 0;j < strlen(s);j++){
if(s[j] == ' '){
Reverse_Word(s,i,j-1);
i=j+1;
}
}
Reverse_Word(s,i,j-1);
return s;
}
剑指 Offer 58 - II. 左旋转字符
思路:申请一块新空间存储前 n 个字符
char* reverseLeftWords(char* s, int n){
int len = strlen(s);
char *result=malloc(sizeof(char)*n);
for(int i = 0,j = 0;i < n;i++,j++){
result[j] = s[i];
}
for(int i = 0,j = n;j < len;j++,i++){
s[i] = s[j];
}
for(int j = len-n,i=0;j < len;j++,i++){
s[j] = result[i];
}
return s;
}
看过代码随想录后:
先整个反转字符串,再分别反转两个区间
收获:先反转整体再反转局部可以达到左旋的效果,代码随想录上是先部分反转后整体
void Reverse_Word(char *s,int a,int b){
int t;
for(;a<b;a++,b--){
t = s[a];
s[a] = s[b];
s[b] = t;
}
}
char* reverseLeftWords(char* s, int n){
int len = strlen(s);
Reverse_Word(s,0,len-1);
Reverse_Word(s,0,len-n-1);
Reverse_Word(s,len-n,len-1);
return s;
}