略
题目:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
替换空格在编程中很多时候会用到,例如在hexo博客的新建文章时,由于文件名不推荐存在空格,所以新建文章时候文章名的空格就会转换成“-”。网络编程中也一样,URL参数中的特殊字符很可能会导致服务器无法获得正确的参数,所以需要转换空格。
转换规则:’%’后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码为32,转换为十六进制为0x20,因此空格替换为”%20“。同理’#’的ASCII码为35,十六进制为0x23,则被替换为”%23“。
分析
耿直的实现方法
最直观的方法就是从头开始扫描字符串,如果遇到空格,则把空格后面的所有字符全部向后移动两个字节,然后再把‘%‘、’2‘、’0‘这三个字符依次插入到空格和空格后两个位置中,再继续向后扫描字符串重复操作直到到达字符串结尾。
但是这样做会有一个问题:每遇到一个空格,都要把空格后面的字符串全部向后移动。假设字符串长度为n,对于每个空格需要移动后面O(n)个字符,如果空格有n个,则总的时间效率会是O(n²)。
换一种方式来思考问题
可以先遍历一次字符串,统计字符串的总长度和字符串中空格的个数。每有一个空格,字符串的长度增加2个字节,最后得到一个新字符串的长度。
可以从 新字符串最后一个字节开始填充字符串,准备两个指针,P1和P2,P1位于原字符串最后一个字符,P2位于新字符串的最后一个字符,把P1位置的字符赋给P2位置,然后向前移动P1,P2,直到P1指向了一个空格为止,这时P1向前移动一格,P2向前移动3格,并把0
、2
、%
插入到这三格中,再然后接着复制,移动,直到碰到第二个空格,依次类推,当P1与P2指向同个位置时候,表明所有空格已经替换完成。
从上面可以看出:所有的字符都仅仅移动了一次,所以这个算法的时间复杂度为O(n)。
代码实现
代码如下:
1 | public class Solution { |
总结
- 换个角度看问题,从前向后与从后向前都要考虑到。
- 注意用StringBuffer的setLength(int long)方法,确保容器大小合适。
- 需要熟练掌握常用的方法,例如
setCharAt()
,charAt()
,setLength()
…等。