面试题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; } };
学习的博客多用于在笔记中,防止笔记过于臃肿,所以将样例及运行结果放在博客中,后以超链接的形式记录在笔记中,所以有些博文过于单薄。如果有小伙伴遇到问题欢迎评论,看到就会回复,学渣一枚,加油努力。