面试题5:替换空格

题目描述:请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

 

由于Java中字符串(String)是不可变类型,所以不能修改原字符串。只能新建一个字符串实现。

 

实现思路:

新建一个StringBuilder,遍历字符串中的每一个字符,如果是' ',就将"%20"拼接到新字符串中,如果不是空格,就将该字符拼接到新字符串中。

 

复杂度分析:

时间复杂度:遍历使用 O(N) ,每轮添加(修改)字符操作使用 O(1)

空间复杂度 O(N) :Java 新建的 StringBuilder 都使用了线性大小的额外空间。

class Solution {
    public String replaceSpace(String s) {
        StringBuilder res = new StringBuilder();
        char[] chars = s.toCharArray();
        for (char ch :chars){
            if (ch == ' '){
                res.append("%20");
            }else{
                res.append(ch);
            }
        }
        return res.toString();
    }
}

当然这道题的目的显然不是这种无意义的做法。

 

在C++中,字符串可以被修改,那么在C++中如何实现?

 

最直接的想法就是遍历字符串,遇到空格就替换成%20,不过需要注意的,由于%20占三个字符,而空格只占一个字符,所以会产生覆盖原字符问题。

 

在将空格替换成%20前,需要将空格后面的字符向后移动三个位置。

 

对于这种算法的时间复杂度:遍历字符串需要O(N),移动后面字符需要O(N),总的时间复杂度为O(N^2)

时间复杂度更低的算法:

 

从字符串的后面开始复制和替换,使用两个指针p1和p2,p1指向原始字符串的末尾,p2指向替换之后的字符串末尾。

 

当p1不是空格时,复制到p2位置,然后逐个把字符复制到p2位置,直到遇到空格。

 

遇到空格后,将p1向前移动1格,p2位置插入'0',p2-1位置插入'2',p2-2位置插入'%',然后将p2向前移动3格。

 

由于所有的字符都只需要移动一次,所以时间复杂度为:O(N)

class Solution {
public:
    string replaceSpace(string s) {
    int count = 0;
    int len  = s.size();

    for(char c : s){
        if (c == ' ')
        {
            /* code */
            count++;
        }
    }

    s.resize(len + 2 * count);

    //i从字符串的最后一个从后往前,j从字符串的长度最后从后往前
    for (int i = len - 1,j = s.size() - 1; i < j; i--,j--)
    {
        /* code */
        if (s[i] != ' ')
        {
            s[j] = s[i];
        }else{
            s[j] = '0';
            s[j-1] = '2';
            s[j-2] = '%';
            j = j-2;
        }
    }
    return s;
    }
};

 

posted @ 2020-09-25 14:53  硬盘红了  阅读(149)  评论(0编辑  收藏  举报