今天在leetcode上刷了3道字符串反转的题目,在这里记录一下。
1、344.反转字符串:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
//两种解法
//法一:常规的两指针交换
void reverseString(char* s, int sSize){
int left = 0;
int right = sSize-1;
while(left<right)
{
int temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
//法二:使用异或
void reverseString(char* s, int sSize){
int left = 0;
int right = sSize-1;
while(left<right)
{
s[left]=s[left]^s[right];
s[right]=s[left]^s[right]; // b=b^a^a=b^0=b
s[left]=s[left]^s[right]; //a=b^a^b=a^0=a
left++;
right--;
}
}
2、541反转字符串II:给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。
*如果剩余字符少于 k 个,则将剩余字符全部反转。
*如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = "abcdefg", k = 2
输出: "bacdfeg"
这道题的难点在于判断反转前k个还是最后一组全部反转
我们还是用两个指针联动进行交换,前指针是每组的第0个位置,记为left;后指针需要判断,要么是每组的第k个元素,即right=left+k-1,要么是这组的最后一个元素,也就是整个数组的最后元素,即right=len-1。
//参考别人的。2k为一个组,反转前k个;如果不足2k,但是大于k,则反转这个组的全部
char * reverseStr(char * s, int k){
int len = strlen(s); //获得数组长度
for(int i=0;i<len;i=i+2*k)
{
int left = i; //左侧
int right = (i+k-1)<len?(i+k-1):(len-1); //可以检查越界问题,而i+k-1是要交换的左侧
//异或交换
while(left<right)
{
s[left]=s[left]^s[right];
s[right]=s[left]^s[right];
s[left]=s[left]^s[right];
left++;
right--;
}
}
return s;
}
3、577 反转字符串的单词III:给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例 1:
输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc"
注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。
//反转函数
void reverse(char* s,int left,int right)
{
while(left<right)
{
s[left]=s[left]^s[right];
s[right]=s[left]^s[right];
s[left]=s[left]^s[right];
left++;
right--;
}
}
char * reverseWords(char * s){
int left = 0;
int right = 0;
while (s[right++] != '\0') {
if (s[right] == ' ' || s[right] == '\0')
{
reverse(s, left, right - 1);
left = right + 1;
}
}
return s;
}
4、917.仅仅反转字母:给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
示例 1:
输入:"ab-cd"
输出:"dc-ba"
示例 2:
输入:"a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"
示例 3:
输入:"Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"
跳过非字母的元素
char * reverseOnlyLetters(char * S){
int len=strlen(S);
int left=0; //左侧指针
int right=len-1; //右侧指针
while(left<right)
{
while(left<right&& !isalpha(S[left]))
{
left++;
}
while(left<right && !isalpha(S[right]))
{
right--;
}
if(left<right)
{
char temp=S[left];
S[left]=S[right];
S[right]=temp;
left++;
right--;
}
}
return S;
}
参考资料:力扣(LeetCode)
https://leetcode-cn.com/problems/reverse-string/
https://leetcode-cn.com/problems/reverse-string-ii/
https://leetcode-cn.com/problems/reverse-words-in-a-string-iii