力扣训练第八天: 344.反转字符串、541.反转字符串||、剑指offer.05替换空格、151.翻转字符里的单词、● 剑指Offer58-II.左旋转字符串

本文深入探讨了几种常见的字符串操作方法,包括使用双指针技术反转字符串、处理字符串中的空格替换问题、左旋转字符串以及反转字符串中的单词等。通过具体实例展示了如何高效地解决这些问题,并强调了细节处理的重要性。
  • 344.反转字符串
    • 可以说这是一道基础题了, 但是仍旧不能掉以轻心。
    • 方法: 双指针
      • 个人小bug, while中忘记了 left++ 和right--;
      • 附上代码
        void reverseString(char*s, int sSize) {
            int left = 0, right = sSize - 1;
            while (left <= right) {
                char temp = s[left];
                s[left] = s[right];
                s[right] = temp;
                left++;
                right--;
            }
            return s;
        }
  •  541.反转字符串||
    • 怎么说,千万别看名字很一样就觉得题大致相同,其实并非如此!
    • 一刷让我忘记了之前自己的愚笨做法,只是对卡哥的解法有影响,但是具体写起来又是错误百出。
      • /*int size = strlen(s);
            if (size < k) reverse(s, 0, size - 1);
            for (int i = 0; i < size && size > k; i += 2 * k) {
                reverse(s + i, i, i + k - 1);
            }*/  

        这段代码是我的错误,首先我对s的移动没有认识清除,s是数组的头指针,而我们是选择性的对数组内部的一段代码进行操作。                                                                                        

    • 这道题要改变我们的固有思维,就是for循环里,i 不一定就是只能i++, 也可以进行i + = 2 * k的操作,也就是对目标进行一段一段的操作。这种思路要有。
    • 此外,还要读懂题意,要知道当最后不足2k的时候,如果这时是小于k的那么就要都反转,可是如果k的话,依然反转前k个。
    • 还要记得 continue 啊。为什么要有这个呢?因为if外面的那个东东是对最后一步的不确定性进行操作的。
    • 
      char* reverse(char* s, int start, int end) {
          while (start <= end) {
              char temp = s[start];
              s[start] = s[end];
              s[end] = temp;
              start++;
              end--;
          }
          return s;
      }
      char* reverseStr (char* s, int k) {
          
          int size = strlen(s);
          for (int i = 0; i < size; i += 2 * k) {
              if (i + k < size) {
                  reverse(s, i, i + k - 1);
                  continue;
              }
              reverse(s, i, size - 1);
          }
          return s;
      }

       

  • 剑指 Offer 05. 替换空格

    •  替换空格,用 %20 替换,这不是等价替换,需要我们扩充数组。
    • 所以首先计算数组内空格的数量,完后 新建立一个 数组 并且malloc为 (size + 2*count)
    • malloc为 (size + 2*count) 这是不对的, 我们要malloc为 (size + 2*count + 1)给\0留位置
    • 接着利用双指针分别同时遍历两个数组, 若遇到空格 就替换。
      • char* replaceSpace(char* s){
            int len = strlen(s);
            int count = 0;
            for (int i = 0; i < len; i++) {
                if (s[i] == ' ') count++;
            }
            int resSize = (len + 2 * count);
            char* res = (char*)malloc(resSize + 1);
            for (int i = len - 1, j = resSize - 1; i >= 0; i--) {
                if (s[i] == ' ') {
                    res[j] = '0';
                    res[j - 1] = '2';
                    res[j - 2] = '%';
                    j -= 3;
                }
                else {
                    res[j--] = s[i];
                }
            }
            res[resSize] = '\0';
            return res;
        }//
    •  

      1.char* res = (char*)malloc(resSize + 1);

      2.上面那句话中sizeof不加会怎么样 , 其次为什么加1 ?

      3.res[resSize] = '\0';这一步一定要做。

  •  剑指 Offer 58 - II. 左旋转字符串
    •  左旋转字符串: 局部旋转 + 整体旋转 来实现,
    • 具体实现步骤; 1.反转区间为前n的子串。2.反转区间 n到末尾的子串 3. 反转整个字符串
      • void reverse(char* s, int start, int end) {
            while (start <= end) {
                char temp = s[start];
                s[start] = s[end];
                s[end] = temp;
                start++;
                end--;
            }
        }
        char* reverseLeftWords(char* s, int n) {
            int size = strlen(s);
            reverse(s, 0, n - 1);
            reverse(s, n, size -1);
            reverse(s, 0, size - 1);
            return s;
        }
  •  151. 反转字符串中的单词
    •  这道题很别扭,一刷就没有过,一直都是执行出错,二刷又是这样。 
    • 通过写日志发现了好多细枝末节的错误:
      • 一定要有这个::: result[size] = ‘\0’ 这个操作。
        • ‘\0’一般放在字符串的结束处,用来表示字符串的结束,其是ascii值为0的字符的转义。如果一个字符串中没有’\0’这个结束字符,那么这些函数将不能确定字符串的结束位置在哪儿,从而引起一些不必要的错误。
      • 其次,因为我们有三次处理空格的操作,所以一定要清楚自己最后得到数组的长度是多少。
      • 还有就是在复制一个字符串的时候
        •  for (int i = 0; i <= size; i++) {
                  result[i] = s[i];
              }
      • 还有,在反转整个字符串的时候。reverse(result, 0, size - 1);是对0 -size- 1之间的东西进行操作。
      •  
        • void reverse(char* s, int start, int end) {
              for (int i = start, j = end; i < j; i++, j--) {
                  char temp = s[i];
                  s[i] = s[j];
                  s[j] = temp;
              }
          }
          char * reverseWords(char * s){
              int slow = 0, fast = 0;
              int size = strlen(s);
              // 去掉前面的空格
              while (size > 0 && fast < size && s[fast] == ' ') {
                  fast++;
              }
              //
              for (; fast < size; fast++) {
                  if (fast - 1 > 0 && s[fast] == s[fast - 1] && s[fast] == ' ') {
                      continue;
                  }
                  else {
                      s[slow++] = s[fast];
                  }
              }
              if (slow - 1 > 0 && s[slow - 1] == ' ') {
                  size = slow - 1;
              }
              else 
                  size = slow;
              char *result = malloc(sizeof(char) * size + 1);
              for (int i = 0; i <= size; i++) {
                  result[i] = s[i];
              }
              reverse(result, 0, size - 1);
              for (int i = 0; i <= size; i++) {
                  int j = i;
                  while(j < size && result[j] != ' ') {
                      j++;
                  }
                  reverse(result, i, j - 1);
                  i = j;
              }
              result[size] = '\0';
              return result;
          
          }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值