替换空格
问题描述:
请实现一个函数,把字符串 s
中的每个空格替换成"%20"
解题思路
API
- 时间复杂度:
O(n)
,空间复杂度:O(1)
class Solution {
public String replaceSpace(String s) {
if (s == null || s.length() == 0)
return "";
return s.replace(" ", "%20");
}
}
StringBuilder
- 时间复杂度:
O(n)
,空间复杂度:O(n)
class Solution {
public String replaceSpace(String s) {
if (s == null || s.length() == 0)
return "";
StringBuilder sb = new StringBuilder();
for (char c: s.toCharArray()) {
if (c == ' ') sb.append("%20");
else sb.append(c);
}
return sb.toString();
}
}
剑指Offer思路
- 只是为了加深下这种思路的影响,首先统计字符串中空格的数量,然后进行扩容,然后从后往前进行赋值,这样在线性时间内即可完成;如果输入参数为不可变的
String
,就不能使用setLength()
方法,所以用此方法效率会更慢(String
转为遍历StringBuilder
;setLength
方法执行也很慢,其内部扩容主要调用Arrays.copyOf()
和Arrays.fill()
)
class Solution {
public String replaceSpace(String s) {
if (s == null || s.length() == 0)
return "";
// 剑指Offer
StringBuilder sb = new StringBuilder(s);
int count = 0, oldLength = sb.length();
for (int i = 0; i < oldLength; ++i) {
if (sb.charAt(i) == ' ')
count++;
}
int newLength = oldLength + count * 2, idx = newLength - 1;
sb.setLength(newLength);
for (int i = oldLength - 1; i >= 0; --i) {
char c = sb.charAt(i);
if (c == ' ') {
sb.setCharAt(idx--, '0');
sb.setCharAt(idx--, '2');
sb.setCharAt(idx--, '%');
} else {
sb.setCharAt(idx--, c);
}
}
return sb.toString();
}
}
知识点
String、StringBuffer和StringBuilder的相似点与不同点:
- 运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String;String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
- 线程安全;在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的;如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。
- String:适用于少量的字符串操作的情况;StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况;StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况