剑指Offer 05:替换空格
剑指Offer 05:替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
思路
如果想把这道题目做到极致,就不要只用额外的辅助空间了!
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
有同学问了,为什么要从后向前填充,从前向后填充不行么?
从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素向后移动。
「其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。」
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。
代码
public class 替换空格 {
public static void main(String[] args) {
String s = "hello world";
String s1 = replaceSpaces(s);
System.out.println(s1);
}
public static String replaceSpaces(String s) {
//统计字符串中空格的个数
char[] c = s.toCharArray();
int count = 0;
for (int i = 0; i < c.length; i++) {
if (c[i] == ' ') {
count++;
}
}
//扩充数组
char[] newChar = new char[c.length + 2 * count];
//利用双指针,从后向前遍历
int oldPoint = c.length;
int newPoint = newChar.length;
for (int i = oldPoint-1, j = newPoint-1; j >= 0; i--, j--) {
if (c[i] != ' ') {
newChar[j] = c[i];
} else {
newChar[j] = '0';
newChar[j - 1] = '2';
newChar[j - 2] = '%';
j -= 2;
}
}
String s1 = new String(newChar);
return s1;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
此时算上本题,我们已经做了七道双指针相关的题目了分别是:
- 27.移除元素
- 15.三数之和
- 18.四数之和
- 206.翻转链表
- 142.环形链表II
- [344.反转字符串](