【代码随想录算法训练营第八天 | 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字 151.翻转字符串里的单词 卡码网:55.右旋转字符串】

字符串

反转字符串

leetcode

代码随想录

  • 前提
    • 原地修改输入数组
void reverseString(char* s, int sSize) {
    char tmp;
    int i = 0;
    int j = sSize - 1;

    while (i < sSize/2){
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
        
        i++;
        j--;
    }
}

反转字符串2

leetcode

代码随想录

解法一

计数器跨段

char* reverseStr(char* s, int k) {
    int cnt = 0;
    int size = strlen(s);

    while (size > 0){
        int subsize = size < k ? size : k;
        int i = cnt*2*k;
        int j = cnt*2*k + subsize - 1;
        int mid = cnt*2*k + subsize/2;           

        while (i < mid){
            char tmp = s[i];
            s[i] = s[j];
            s[j] = tmp;
            i++;
            j--;
        }

        size = size - 2*k;
        cnt++;
    }
    
    return s;
}

解法二

for循环步长跨段

char * reverseStr(char * s, int k){
    int len = strlen(s);

    for (int i = 0; i < len; i += (2 * k)) {
        //判断剩余字符是否少于 k
        k = i + k > len ? len - i : k;

        int left = i;
        int right = i + k - 1;
        while (left < right) {
            char temp = s[left];
            s[left++] = s[right];
            s[right--] = temp;
        }
    }

    return s;
}

替换数字(ACM)

KamaCoder

代码随想录

  • 要点

    • 很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

      这么做有两个好处:

      1. 不用申请新数组。
      2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
    • 字符串末尾要加上\0,申请内存要预留长度

    • C语言没有'0' <= s[i] <= '9'的格式,得写成s[i] >= '0' && s[i] <= '9'

    • 记得释放内存

    • 数组别名是常量,无法将&array作为二维指针传递

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char replaceNumInStr(char **s, int sizeS){
    int cnt = 0;
    int i;
    
    for (i = 0; i < sizeS; i++){
        if ((*s)[i] >= '0' && (*s)[i] <= '9'){
            cnt++;
        }
    }
    
    int newSize = cnt*6 + sizeS - cnt;
    *s = (char *)realloc(*s, (sizeof(char)*newSize+1));
  
    int cur = newSize-1;  
    for (i = sizeS-1; i >=0; i--){
        if ((*s)[i] >= '0' && (*s)[i] <= '9'){
            (*s)[cur--] = 'r';
            (*s)[cur--] = 'e';
            (*s)[cur--] = 'b';
            (*s)[cur--] = 'm';
            (*s)[cur--] = 'u';
            (*s)[cur--] = 'n';
        }
        else{
            (*s)[cur--] = (*s)[i];
        }
    }
    
    return newSize;
}

void main(){
    int sizeStr = 0;
    char *str= malloc(sizeof(char)*10000);
    
    fgets(str, 10000, stdin);
    str[strcspn(str, "\n")] = '\0';
    sizeStr = replaceNumInStr(&str, strlen(str));
    printf("%s\n", str);

    free(str);
        
    return;
}

反转字符串中的单词

leetcode

代码随想录

  • 前提
    • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括
    • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个
    • 拓展:不使用额外的空间
  • 解题思路
    • 移除多余空格
      • 移除元素使用快慢指针,快指针遍历搜索满足条件的元素,慢指针指向新数组的尾部
    • 将整个字符串反转
      • 相向双指针
    • 将每个单词反转
      • 整个字符串for循环遍历
      • 单词相向双指针反转
void removeSpaces(char *s){
    int slow = 0;
    int fast = 0;

    for (;fast <= strlen(s); fast++){
        if (s[fast] != ' '){
            s[slow++] = s[fast];
        }
        else if (fast > 0 && s[fast-1] != ' '){
            s[slow++] = s[fast];
        }
    }

    s[slow-2] = s[slow-2] == ' ' ? '\0' : s[slow-2];
}

void reverseString(char *s, int slow, int fast){
    char tmp;
    while (slow < fast){
        tmp = s[slow];
        s[slow++] = s[fast];
        s[fast--] = tmp;
    }
}


char* reverseWords(char* s) {
    removeSpaces(s);
    reverseString(s, 0 , strlen(s)-1);

    int slow = 0;
    for (int i = 0; i <= strlen(s); i++){
        if (s[i] == ' ' || s[i] == '\0'){
            reverseString(s, slow, i-1);
            slow = i + 1;
        }
    }

    return s;
}

右旋转字符串

kamaCoder

代码随想录

  • 前提

    • 拓展:不使用额外的空间
  • 思路:

    • 反转母串之后再反转子串

    img

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverseString(char *s, int start, int end){
    char tmp;
    while (start < end){
        tmp = s[start];
        s[start++] = s[end];
        s[end--] = tmp;
    }
}

void main(){
    int k;
    char *s = malloc(sizeof(char)*10000);
    
    scanf("%d", &k);
    //跨行输入用getchar()吸收回车
    getchar();
    fgets(s, 10000, stdin);
    s[strcspn(s, "\n")] = '\0'; 
    
    reverseString(s, 0, strlen(s)-1);
    reverseString(s, 0, k-1);
    reverseString(s, k, strlen(s)-1);
    
    printf("%s", s);
    
    free(s);
    
    return;
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值