LeetCode-空格替换问题

简介: 笔者比较笨,所以会写的很详细,方便自己后序复盘和分享给别人!希望大佬们不要嫌弃我的事多~哈哈哈!感谢大佬们支持!

题目

b365632b5f0e4344862fb003e7df37c8.png

笔者比较笨,所以会写的很详细,方便自己后序复盘和分享给别人!希望大佬们不要嫌弃我的事多~哈哈哈!感谢大佬们支持!


题目链接:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/


思路

  • 根据规律可知,替换之后的长度 = 原来替换前的长度 +空格个数*2 (不包括\0) ->所以替换后末尾要手动放\0,或者替换过程把\0也放过去
  • 所以:第一步:遍历字符串,求出空格个数
  • 求出替换之后的长度记为:newlength 原来的长度记为:length
  • 进行填充,从后往前填充,用两个变量来控制, i 下标范围:[0,length] ->这种情况包含了\0,要把\0也替换过去 而若下标范围为:[0,length) ->这种情况是没有把\0也替换过去,所以最后要在newlength位置手动放\0
  • pos取值范围:[0,newlength] /[0,newlength)
  • 如果i指向的字符不是空格,就把此时的字符放到pos位置,pos–,i–
  • 如果是空格就放%20到pos位置,pos–三次,i–一次

手动最后位置放\0

235f87483173433d8a087351604559af.png

方法1:从后往前替换

写法1:下标范围为:**[0,newlength) **和 [0,newlength) 最后拷贝完手动放\0

8225768b5eef4c60a60589e38c8a9989.png

#include<stdio.h>
#include<string.h>
void ReplaceSpace(char* str, int length)
{
    //1.计算空格的个数
    int i = 0;
    int spcount = 0;
    for (i = 0; i < length; i++)
    {
      if (str[i] == ' ')
        spcount++;
    }
    //2.计算替换空格后新的长度和最后的位置
    int newlengh = length + spcount * 2;
    int pos = newlengh - 1;
    //3.从后往前填充
    for (i = length - 1; i >= 0; i--)
    {
      //空格
      if (str[i] == ' ')
      {
        str[pos--] = '0';
        str[pos--] = '2';
        str[pos--] = '%';
      }
      //非空格
      else
      {
        str[pos--] = str[i];
      }
    }
    //最后手动在newlength位置放\0
    str[newlengh] = '\0';
}
int main()
{
  char arr[20] = " We Are Happy";
  ReplaceSpace(arr, strlen(arr));
  printf("%s\n", arr);
  return 0;
}

写法2:下标范围为:[0,newlength][0,newlength] 直接把\0也后移

6743f3a7e5ce4594bb0fc1686073a19d.png

void ReplaceSpace(char* str, int length)
{
  assert(str);
  //统计空格的个数
  int count = 0;
  for (int i = 0; i < length; i++)
  {
    if (str[i] == ' ')
    {
      count++;
    }
  }
  //计算替换后的长度 = 原来长度+空格个数*2
  int newlength = length + count * 2;
  int pos = newlength;
  //替换 -从后往前覆盖
  //如果不是空格就把pos位置的字符放到pos位置
  //如果是空格就在pos位置往前放%20
  // \0也要替换,所以长度为:[0,length]
  //从后往前存放
  for (int i = length; i >= 0; i--)
  {
    if (str[i] == ' ')
    {
      //如果是空格就在pos位置往前放 %20
      str[pos--] = '0';
      str[pos--] = '2';
      str[pos--] = '%';
    }
    else
    {
      str[pos--] = str[i];
    }
  }
}
int main()
{
  char arr[50] = " WeAreHappy";
  ReplaceSpace(arr, strlen(arr));
  printf("%s\n", arr);
  return 0;
}

方法2:开辟新空间

思路

  • 第一步:遍历字符串,求出空格个数为count
  • 求出替换之后的长度记为:newlength 原来的长度记为:length,newlength = length + count*2 求出字符串的长度是不包含\0的!!
  • 开辟一个大小为newlength+1大小的数组arr (多加一个空间是为了存放\0
  • 分别使用变量控制下标 i 控制str数组 j控制arr数组
    如果i指向的不是空格,就把i指向的内容放到arr数组的j位置,i++,j++
    如果是i指向的是空格,就在arr数组后面覆盖%20,j++三次,然后i++跳过空格,
    不管怎样i都要++
  • 最后把arr数组的内容拷贝回去,然后释放掉arr
#include<stdlib.h>
//开辟新空间
void ReplaceSpace(char* str, int length)
{
    //统计空格个数
  int count = 0;
  int i = 0;
  for (i = 0; i < length; i++)
  {
    if (str[i] == ' ')
    {
      count++;
    }
  }
  int newlength = length + count * 2;  //计算出的长度不包括\0
  char* arr = (char*)malloc(sizeof(char) * (newlength+1));//要存放\0,所以要多开辟一个空间
  if (arr == NULL)
  {
    printf("malloc fail\n");
    exit(-1);
  }
  //分别使用变量控制下标 i 控制str数组 j控制arr数组
  //如果i指向的不是空格,就放到arr数组的j位置,i++,j++ 
  //如果是i指向的是空格,就在arr数组中替换为%20,i++一次,j++三次
  //不管怎样i都要++
  int j = 0;
  for (i = 0; i < length; i++)
  {
        //i指向的是空格
    if (str[i] == ' ')
    {
      arr[j++] = '%';
      arr[j++] = '2';
      arr[j++] = '0';
    }
    else
    {    
      arr[j++] = str[i];
    }
  }
    //在newlength位置放\0
  arr[newlength] = '\0';
  //拷贝回去,把\0也拷贝过去,所以范围为:[0,newlength]
  for (j = 0; j <=newlength; j++)
  {
    str[j] = arr[j];
  }
    //最后要释放空间
  free(arr);
  arr = NULL;
}
int main()
{
  char arr[50] = "WeAre Happy";
  ReplaceSpace(arr, strlen(arr));
  printf("%s\n", arr);
  return 0;
}

代码

char* replaceSpace(char* s){
    /*
  int i = 0;
  int len = strlen(s);
  int count = 0;
  //统计空格个数
  for(i = 0;i<len;i++)
  {
      if(s[i] == ' ')
      {
          count++;
      }
  }
  //开辟新空间
  int newlength = count*2+len;
  char* str = (char*)malloc(sizeof(char)*(newlength+1));    //多开辟一个空间存放\0
  int j = 0;
  for(i = 0;i<len;i++)
    {
        if(s[i] == ' ')
        {
            str[j++] = '%';
            str[j++] = '2';
            str[j++] = '0';   
        }
        else
        {
            str[j++] = s[i];
        }
    }
    str[j] = '\0';
    //或者str[newlength] = '\0'  在最后位置放\0
    return str;
    */
    //法2:原地扩容
    int i = 0;
  int len = strlen(s);
  int count = 0;
  //统计空格个数
  for(i = 0;i<len;i++)
  {
      if(s[i] == ' ')
      {
          count++;
      }
  }
  //开辟新空间
  int newlength = count*2+len;
  s = (char*)realloc(s,sizeof(char)*(newlength+1));    //多开辟一个空间存放\0
  //从后往前
  int pos = newlength;
  s[pos] = '\0';
  for(i = len ;i> 0;i--)
  {
      if(s[i] == ' ')
      {
          s[pos--] = '0';
          s[pos--] = '2';
          s[pos--] = '%';
      }
      else{
          s[pos--] = s[i];
      }
  } 
  return s;
}
相关文章
|
6月前
leetcode-1219:黄金矿工
leetcode-1219:黄金矿工
79 0
|
6月前
|
消息中间件 Kubernetes NoSQL
LeetCode 3、28、1351
LeetCode 3、28、1351
顺手牵羊(LeetCode844.)
好多同学说这是双指针法,但是我认为叫它顺手牵羊法更合适
78 0
|
索引
|
存储 Python
LeetCode 66. Plus One
给定表示非负整数的非空数字数组,加上整数的1。 存储数字使得最高有效数字位于列表的开头,并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零,除了数字0本身。
88 0
LeetCode 66. Plus One
leetcode第44题
时间复杂度:text 长度是 T,pattern 长度是 P,那么就是 O(TP)。 空间复杂度:O(TP)。 同样的,和第10题一样,可以优化空间复杂度。
leetcode第44题
leetcode第51题
较经典的回溯问题了,我们需要做的就是先在第一行放一个皇后,然后进入回溯,放下一行皇后的位置,一直走下去,如果已经放的皇后的数目等于 n 了,就加到最后的结果中。然后再回到上一行,变化皇后的位置,然后去找其他的解。 期间如果遇到当前行所有的位置都不能放皇后了,就再回到上一行,然后变化皇后的位置。再返回到下一行。 说起来可能还费力些,直接看代码吧。
leetcode第51题
leetcode第54题
在 leetcode 的 solution 和 discuss 看了下,基本就是这个思路了,只是实现上有些不同,怎么用来标记是否走过,当前方向,怎么遍历,实现有些不同,但本质上是一样的。就是充分理解题意,然后模仿遍历的过程。
101 0
leetcode第54题
|
存储
leetcode第52题
可以发现对于同一条副对角线,row + col 的值是相等的。 对于同一条主对角线,row - col 的值是相等的。 我们同样可以用一个 bool 型数组,来保存当前对角线是否有元素,把它们相加相减的值作为下标。 对于 row - col ,由于出现了负数,所以可以加 1 个 n,由 [ - 3, 3 ] 转换为 [ 1 , 7 ] 。
leetcode第52题