剑指Offer 05.替换空格
- 1 题目
- 2 思路--双指针法
- 3 代码
- 3.1 C++版本
- 3.2 C版本
- 3.3 Java版本
- 3.4 Python3版本
- 3.5 JavaScript版本
 
- 4 总结
1 题目
题源链接
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = “We are happy.”
 输出:“We%20are%20happy.”
限制:
0 <= s 的长度 <= 10000
2 思路–双指针法
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
 i指向新长度的末尾,j指向旧长度的末尾。
 
 动画演示
其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
3 代码
3.1 C++版本
class Solution {
public:
    string replaceSpace(string s) { //双指针法
        int cnt = 0;    //记录空格个数
        int lenOld = s.size();
        for (int i = 0; i < s.size(); i++)
            if (s[i] == ' ')
                cnt++;
        //  扩充s为空格替换成%20之后的大小
        s.resize(s.size() + cnt * 2);
        int lenNew = s.size();
        for (int i = lenNew - 1, j = lenOld - 1; j < i; i--, j--) {
            if (s[j] != ' ')
                s[i] = s[j];
            else {
                s[i--] = '0';
                s[i--] = '2';
                s[i] = '%';
            }
        }
        return s;
    }
};
3.2 C版本
char* replaceSpace(char* s){
    //统计空格数量
    int count = 0;
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (s[i] == ' ') {
            count++;
        }
    }
    //为新数组分配空间
    int newLen = len + count * 2;
    char* result = malloc(sizeof(char) * newLen + 1);
    //填充新数组并替换空格
    for (int i = len - 1, j = newLen - 1; i >= 0; i--, j--) {
        if (s[i] != ' ') {
            result[j] = s[i];
        } else {
            result[j--] = '0';
            result[j--] = '2';
            result[j] = '%';
        }
    }
    result[newLen] = '\0';
    return result;
}
3.3 Java版本
public String replaceSpace(String s) {
    if(s == null || s.length() == 0){
        return s;
    }
    //扩充空间,空格数量2倍
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        if(s.charAt(i) == ' '){
            str.append("  ");
        }
    }
    //若是没有空格直接返回
    if(str.length() == 0){
        return s;
    }
    //有空格情况 定义两个指针
    int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
    s += str.toString();
    int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
    char[] chars = s.toCharArray();
    while(left>=0){
        if(chars[left] == ' '){
            chars[right--] = '0';
            chars[right--] = '2';
            chars[right] = '%';
        }else{
            chars[right] = chars[left];
        }
        left--;
        right--;
    }
    return new String(chars);
}
3.4 Python3版本
class Solution:
    def replaceSpace(self, s: str) -> str:
        # method 1 - Very rude
        return "%20".join(s.split(" "))
        # method 2 - Reverse the s when counting in for loop, then update from the end.
        n = len(s)
        for e, i in enumerate(s[::-1]):
            print(i, e)
            if i == " ":
                s = s[: n - (e + 1)] + "%20" + s[n - e:]
            print("")
        return s
3.5 JavaScript版本
/**
 * @param {string} s
 * @return {string}
 */
 var replaceSpace = function(s) {
   // 字符串转为数组
  const strArr = Array.from(s);
  let count = 0;
  // 计算空格数量
  for(let i = 0; i < strArr.length; i++) {
    if (strArr[i] === ' ') {
      count++;
    }
  }
  let left = strArr.length - 1;
  let right = strArr.length + count * 2 - 1;
  while(left >= 0) {
    if (strArr[left] === ' ') {
      strArr[right--] = '0';
      strArr[right--] = '2';
      strArr[right--] = '%';
      left--;
    } else {
      strArr[right--] = strArr[left--];
    }
  }
  // 数组转字符串
  return strArr.join('');
};
4 总结
- 时间复杂度:O(n)
- 空间复杂度:O(1)
By – Suki 2023/2/3



















