1.字符串逆序的第一种类型,即反转字符串,力扣557. 反转字符串中的单词
void reverseString(char* s, int sSize){
int left=0;
int right=sSize-1;
while(left<right){
char tmp=s[left];
s[left++]=s[right];
s[right--]=tmp;
}
return *s;
}
思路即为用两个指针,一个指针指向第一个元素,另一个指针指向最后一个元素,进行前后反转
2.力扣541. 反转字符串 II
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
该题的思路为:反转k个字符,之后跳过k个字符,如此循环,如果剩余的字符小于k个大于2k个,则反转前k个,剩下的不变。
如果剩余的字符小于k个,那么全部反转
该题具体实现时,用到了局部反转的思想,这个在之后的题目也会用到。即规定反转开始的位置和反转结束的位置,在其中进行如题目一所示的字符串逆序
开始起始的位置start为0,起始end要判断与len(即字符串长度)的关系 int end=k<len?k-1:len-1 看首先要反转的k个字符的k是否小于字符串长度,如果小于那么结束位置可以为k-1,否则为len-1(k-1就已经越界了)`
char*reverse(char* s,int key){
int len=strlen(s);
int start=0;
int end=k<len?k-1:len-1;//看k是否比数组的总长度要小,如果小,那么初始的end(end是个下标而非长度)就为k-1,否则为len-1
while(start<len&&end<len){//在确保start和end都小于len的情况下
int i,j=0;
for( i=start, j=end;i<j;i++,j--){
s[i]^=s[j];
s[j]^=s[i];
s[i]^=s[j];
}
start+=2*k;//每次局部反转完之后start,end都会发生相应的改变,start会向后移2k,end也会移2k
end=end+2*k<len-1?end+2*k:len-1;
}
return s;
}`
3.用递归的方式实现字符串逆序
void reverse_string(char* arr)
{
int len = strlen(arr);
char tmp = *arr;
*arr = *(arr + len - 1);
*(arr + len - 1) = '\0';//如果此时不将最后一个置为'\0',无法将中间要逆序的部分当做字符串来看待,故加入一个临时的'\0',等待逆序完了再将最后一位放入tmp
if (strlen(arr + 1) >= 2)
reverse_string(arr + 1);
*(arr + len - 1) = tmp;
}
4.反转字符串三 力扣557. 反转字符串中的单词 III
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例:
输入:“Let’s take LeetCode contest”
输出:“s’teL ekat edoCteeL tsetnoc”
char *reverseword(char *s){
int length=strlen(s);
int i=0;
while(i<length){
int start=i;
while(i<length&&s[i]!=' '){
i++;
}
int left=start; //左指针
int right=i-1; //右指针,因为i已经是在空格位置了,所以right需要是i-1
while(left<right){
char tmp=s[left];
s[left]=s[right];
s[right]=tmp;
left++;
right--;
}
while(i<length&&s[i]==' '){//该单词反转完成,反转下一个单词
i++;//将i由指向空格处改为指向下一个字符处
}
}
return s;
}
5.反转字符串中的元音字母
给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现不止一次。
法一:利用双指针法判断
//判断是不是元音
bool isVowel(char c){
if(c == 'a' || c == 'e' ||c == 'i' ||c == 'o' ||c == 'u' || c == 'A' ||c == 'E' ||c == 'I' ||c == 'O' ||c == 'U')
return true;
return false;
}
char * reverseVowels(char * s){
int left = 0;
int right = strlen(s)-1;
printf("%s\n",s);
while(left < right){
//如果不是元音,移动下标
if(!isVowel(s[left])){
left++;
if(left >right)
return s; //注意每当left>right时就会直接跳出,下面都是如此
}
if(!isVowel(s[right])){
right--;
if(left >right)
return s;
}
//左右都是元音,开始交换
if(isVowel(s[left]) && isVowel(s[right])){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
if(left >right)
return s;
}
}
return s;
}
利用下标进行原数组的反转
利用循环遍历原数组,并且开辟一个新数组,遇到元音字母的时候,将该元音字母的下标存入到新数组中,并且记录新数组的长度,当新数组的长度大于等于2时,则利用新数组中存的元音字母下标对原数组中的元音字母进行反转(逆序)。
char * reverseVowels(char * s){
char vowel[]={"aoeiuAOEIU"};
int length=strlen(s);
int pos[300000]={0};
int m=0;
for(int i=0;i<length;i++){
if(strchr(vowel,s[i])){
pos[m]=i;//**开辟新数组记录原字符串中元音字母的下标**
m++;
}
}
if(m>=2){
for(int i=0;i<m/2;i++){//**利用下标对原字符串中的元音字母进行逆序**
char temp=s[pos[i]];
s[pos[i]]=s[pos[m-i-1]];
s[pos[m-i-1]]=temp;
}
}
return s;
}
6.牛客OR62 倒置字符串 I like beijing. 经过函数后变为 beijing. like I
总体思路:先将整个字符串反转,再将每个单词反转
值得注意的是,将整个字符串反转与将每个单词反转用一个函数,而如果用题目一的函数,则无法很好地反转,故此处还是局部反转思想,传入函数的参数为要反转的边界值
void reverse(char *left,char *right){
assert(left&&right);//首先断言,看看是否为空指针
while(left<right){
char tmp=*left;
*left=*right;
*right=tmp;
left++;
right--;
}
}
int main(){
char arr[101]={0};
gets(arr);
int len=strlen(arr);
reverse(arr,arr+len-1);//首先将整个字符串反转
char* cur=arr;
while(cur){
char* start=cur;//start来定位每次cur的初始位置
while(*cur!=' '&&*cur!='\0'){//cur定位的是翻转每一个单词的最后一个位置,不到空格或者不到'\0',cur会一直向后移动
cur++;
}
reverse(start,cur-1);
cur++;//此时cur指向空格处,cur++来到了下一个单词
}
}