思路

看到题的第一反应就是顺序遍历这个字符串,遇到空格就替换。

不过《剑指offer》这本书里详细的阐述了这种算法的时间复杂度是O(n^2),因为对一个长度为n的字符串来说,每一次替换其实就是要把空格之后的部分挪动两次。

这种代码很好写。

Java版本

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @return string字符串
     */
    public String replaceSpace(String s) {
        // write code here
        int len = s.length();
        char[] chars = s.toCharArray();
        List<String> dest = new ArrayList<>();
        for (char str : chars) {
            if (str == ' ') {
                dest.add("%20");
            } else {
                dest.add(String.valueOf(str));
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        dest.forEach(stringBuilder::append);
        return stringBuilder.toString();
    }
}

执行时间115ms。

另外书中提到了一种时间复杂度为O(n)的解法,看起来需要遍历两次字符串,其实效果更好。主要的思路就是首先计算出原字符串里有多少个空格,然后新建一个字符串,这个字符串的长度是原字符串长度加上两倍的空格数量。

然后遍历原字符串,将每一个字符复制到新字符串里,逢空格进行特殊处理即可。

Java版本代码

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @return string字符串
     */
    public String replaceSpace(String s) {
        // write code here
        int len = s.length();
        char[] originalString = s.toCharArray();
        int numberOfBlanks = 0;
        for (char c : originalString) {
            if (c == ' ') {
                numberOfBlanks += 1;
            }
        }
        int newStringLen = len + numberOfBlanks * 2;
        char[] newString = new char[newStringLen];
        for (int i = len - 1, j = newStringLen - 1; i >= 0; i--) {
            if (originalString[i] == ' ') {
                newString[j--] = '0';
                newString[j--] = '2';
                newString[j--] = '%';
            } else {
                newString[j--] = originalString[i];
            }
        }
        return String.valueOf(newString);
    }
}

这段代码的执行时间就缩短到了21ms,效果非常好。

C语言的效率更高,只需要5ms:

C语言版本

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


char* replaceSpace(char* s) {
    // write code here
    int originalLength = strlen(s), numberOfBlanks = 0;

    // 第一次遍历得到数组长度和空格长度
    for (int i = 0; i < originalLength; i++)
    {
        if (s[i] == ' ')
        {
            numberOfBlanks += 1;
        }
    }
    // 替换后的字符串长度
    int newStringLength = originalLength + numberOfBlanks * 2;
    // 分配一段内存给新的字符串用
    char *newString = (char *)malloc(newStringLength + 1);
    for (int i = originalLength - 1, j = newStringLength - 1; i >= 0; i--)
    {
        if (s[i] == ' ')
        {
            newString[j--] = '0';
            newString[j--] = '2';
            newString[j--] = '%';
        }
        else
        {
            newString[j--] = s[i];
        }
    }
    newString[newStringLength + 1] = '\0';
    return newString;
}