2020/08/10 字符串反转

今天在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

https://leetcode-cn.com/problems/reverse-only-letters/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值