难度等级:简单
上一篇算法:
力扣此题地址:
1.题目:替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
2.解题思路:
1. 先计算新数组总的长度,由于空格换成 "%20",所以每个空格会额外多出两个字符。所以新的长度 = 原来长度 + 空格数 * 2。
2. 准备两个指针 P1, P2。P1 指向原始字符串的末尾,P2 指向新字符串的末尾。
3. 接下来向前移动指针 P1,逐个把它指向的字符复制到 P2 指向的位置,直到碰到了第一个空格为止。碰到第一个空格后,把 P1 向前移动 1 格,在 P2 之前插入字符串 "%20"。由于 "%20" 的长度为 3, 同时也需要把 P2 向前移动 3 格。
4. 反复操作 3 步骤,当 P1 和 P2 指向同一个位置时,表明所有空格都已经替换完毕。所有的字符都只复制(移动)一次,所以时间复杂度为 O (n)。
3.知识补充:
有同学问了,为什么要从后向前填充,从前向后填充不行么?
从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。
而从后向前遍历,只需要移动需要移动的即可。
**其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。**
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。
4.代码实现:
public String replaceSpace(StringBuffer str) {
if(str==null)
return null;
int numOfblank = 0;//空格数量
int len=str.length();
for(int i=0;i<len;i++){ //计算空格数量
if(str.charAt(i)==' ')
numOfblank++;
}
str.setLength(len+2*numOfblank); //设置长度
int oldIndex=len-1; //两个指针
int newIndex=(len+2*numOfblank)-1;
while(oldIndex>=0 && newIndex>oldIndex){
char c=str.charAt(oldIndex);
if(c==' '){
oldIndex--;
str.setCharAt(newIndex--,'0');
str.setCharAt(newIndex--,'2');
str.setCharAt(newIndex--,'%');
}else{
str.setCharAt(newIndex,c);
oldIndex--;
newIndex--;
}
}
return str.toString();
}