剣はオファーを指します--05 はスペースと 58 の左利きの文字列を置き換えます


1. Jianzhi Offer–05. スペースを置き換えます

話題はこんな感じ

ここに画像の説明を挿入

文字列s内のスペースを文字列「%20」に置き換えるという意味で、1文字だけ置き換える場合は元の配列で直接置き換えることもできますが、スペースを文字列で置き換えるので、元の配列で置き換えてください、元の配列元の内容は上書きされ、長さが足りないため、この時点で文字配列を動的に開く必要があります.この配列の大きさは? 最悪のケース、つまり、この時点で元の配列の 3 倍の長さのすべてのスペースの場合を考えてみますが、開いた配列のサイズは格納されている有効な文字のみであり、'\0' は数えられたので、もっとあります スペースを開けてください。誰かが文字列 s 内の空白文字の数 (count) を数えることができ、新しく開かれた配列空間のサイズは、元の配列 s のサイズに count*2 を加えた 1 になります。

char* replaceSpace(char* s){
    
    
  int count = 0;
  for(int i = 0;i<strlen(s);i++)
  {
    
    
    if(s[i]==' ')
    {
    
    
      count++;
    }
  }
  
  int len = strlen(s);
  char*ret = (char*)malloc(sizeof(char)*(len+(count*2)+1));
  //char*ret = (char*)malloc(sizeof(char)*(len*3+1));可以这样写

  int j = 0;
  for(int i = 0;i<strlen(s);i++)
  {
    
    
    if(s[i] ==' ')
    {
    
    
        ret[j++] = '%';
        ret[j++] = '2';
        ret[j++] =  '0'; 
    }

    else
    {
    
    
      ret[j++] = s[i];
    }
  }
  ret[j] = '\0';//这里为何要对其数组ret数组有效字符数据的下一位赋值为字符'\0'
  //因为返回首地址,找的是'\0\结束,如果不赋值为'\0',有可能字符数组要过了很久才是'\0,这样会造成越界访问,所以要对其赋值为'\0'。
  return ret;
}

2. 剣はオファー 58 を指します。

タイトルはこんな感じです
ここに画像の説明を挿入
実は変数 n を与えて n より前の文字を後ろに回転させてから n より後の文字を前に回転させます

単純なローテーション 最も
単純な方法を使用できます。まず最初の文字を保存してから、次の文字を 1 つずつ前方にカバーし、n 回循環しますが、時間の複雑さは O(n^2) です。
ここに画像の説明を挿入

char* reverseLeftWords(char* s, int n) {
    
    
    int len = strlen(s);
    int k = n % len;//当要旋转的长度大于了数组的长度,这样就会造成重复操作,
    //所以对其取模,保证最多旋转字符串长度,保证不会不会重复


    while (k--)
    {
    
    
        char tmp = s[0];
        int i = 0;
        for (i = 0; i < strlen(s) - 1; i++)
        {
    
    

            s[i] = s[i + 1];
        }
        s[i] = tmp;
    }

    return s;
}


このように、時間計算量は O(n^2) となり、タイムアウトが表示され、いくつかのユースケースは通過できません

パーティションのローテーション

最初に 0 ~ n-1 の文字を反転し、次に [n, len-1] の間の文字を反転し、最後に全体を反転します。
ここに画像の説明を挿入

void reserve(char* str, int left, int right)
{
    
    
    while (left < right)
    {
    
    
        char tmp = str[left];
        str[left] = str[right];
        str[right] = tmp;

        left++;
        right--;
    }
}

char* reverseLeftWords(char* s, int n) {
    
    

    int len = strlen(s);
    int k = n % len;

    reserve(s, 0, k - 1);
    reserve(s, k, len - 1);
    reserve(s, 0, len - 1);

    return s;
}

別の配列を開き、新しい配列にn以降の文字列を代入し、0から順に値を代入し、新しい配列の後ろに0~n-1の文字を順番に挿入する

ここに画像の説明を挿入
新しい配列を開く必要があるだけで、時間の複雑さは O(n)、空間の複雑さは O(n) です。

char* reverseLeftWords(char* s, int n) {
    
    
    int len = strlen(s);
    int k = n % len;

    char* ret = (char*)malloc(sizeof(char) * len);
    int i = 0;
    int j = k;
    for (i = 0, j = k; j < len; j++, i++)
    {
    
    
        ret[i] = s[j];
    }
    int m = 0;
    while (m < k)
    {
    
    
        ret[i++] = s[m++];
    }

    for (int x = 0; x < len; x++)
    {
    
    
        s[x] = ret[x];
    }

    return s;
}


おすすめ

転載: blog.csdn.net/m0_67768006/article/details/130374319