剑指Offer 05.替换空格
目录
- 剑指Offer 05.替换空格
- 05.替换空格
- 题目
- 代码(容易想到的)
- 利用库函数的方法
- 题解(时间复杂度更低)
- 面试:为什么java中String类型是不可变的
05.替换空格
题目
官网题目地址
代码(容易想到的)
class Solution {
public String replaceSpace(String s) {
String result = "";
for(int i=0; i < s.length();i++)
{
char c = s.charAt(i);
if(Character.isWhitespace(c)){
result+="%20";
}else{
result+=c;
}
}
return result;
}
}
这段代码实现了将字符串 s 中的空格替换为 %20。具体来说,它使用了一个 for 循环遍历字符串 s 中的每一个字符,当遇到空格时,将其替换为 %20,否则直接将字符添加到结果字符串 result 中。
知识点:
- 获取字符串中某个字符的方法
charAt()
- 判断某个字符是否为空格的方法
Character.isWhitespace()
利用库函数的方法
替换字符串的两种方法
class Solution {
public String replaceSpace(String s) {
return s.replaceAll(" ","%20"); //可以接受正则表达式
}
}
class Solution {
public String replaceSpace(String s) {
return s.replace(" ","%20"); //速度快
}
}
replace() 方法用于将一个字符串中的某个字符或字符串替换为另一个字符或字符串。它的语法如下:
public String replace(char oldChar, char newChar)
public String replace(CharSequence target, CharSequence replacement)
其中,第一个参数可以是一个字符,第二个参数可以是一个字符或字符串。方法的返回值是一个新的字符串,它是替换后的结果。
另一个方法是 replaceAll(),它与 replace() 方法相似,不同之处在于它可以接受一个正则表达式作为参数,用于匹配需要替换的子字符串。它的语法如下:
public String replaceAll(String regex, String replacement)
其中,第一个参数是需要替换的子字符串的正则表达式,第二个参数是替换后的字符串。方法的返回值是一个新的字符串,它是替换后的结果。
题解(时间复杂度更低)
① 在字符串尾部填充任意字符,使得字符串的长度等于替换之后的长度。因为一个空格要替换成三个字符(%20),所以当遍历到一个空格时,需要在尾部填充两个任意字符。
② 令 P1 指向字符串原来的末尾位置,P2 指向字符串现在的末尾位置。P1 和 P2 从后向前遍历,当 P1 遍历到一个空格时,就需要令 P2 指向的位置依次填充 02%(注意是逆序的),否则就填充上 P1 指向字符的值。从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。
③ 当 P2 遇到 P1 时(P2 <= P1),或者遍历结束(P1 < 0),退出。
public String replaceSpace(StringBuffer str) {
int P1 = str.length() - 1;
for (int i = 0; i <= P1; i++)
if (str.charAt(i) == ' ')
str.append(" ");
int P2 = str.length() - 1;
while (P1 >= 0 && P2 > P1) {
char c = str.charAt(P1--);
if (c == ' ') {
str.setCharAt(P2--, '0');
str.setCharAt(P2--, '2');
str.setCharAt(P2--, '%');
} else {
str.setCharAt(P2--, c);
}
}
return str.toString();
}
📌java中 String是不可变的不能原地修改,C++可以原地修改
面试:为什么java中String类型是不可变的
在 Java 中,String 类型是不可变的,也就是说,一个 String 对象一旦被创建,它的值就不能被修改。这是因为 String 类型被设计成是一种不可变的类型,具有以下几个原因:
安全性
由于 String 类型是不可变的,因此在多线程环境下,多个线程可以同时访问同一个 String 对象,而不必担心数据被修改。如果在多线程环境下,对可变的字符串进行修改,可能会导致数据竞争和不一致性问题,而这些问题可能会导致程序崩溃或者产生错误的结果。
性能
由于 String 类型是不可变的,因此在对 String 对象进行拼接、截取、替换等操作时,会创建新的 String 对象,而原来的 String 对象不会被修改。这样做的好处是,可以避免在修改字符串时频繁创建新的对象,从而提高程序的性能。
缓存
由于 String 类型是不可变的,因此可以使用字符串缓存来提高程序的性能。在 Java 中,字符串常量池是一种字符串缓存机制,它可以缓存字符串常量,避免重复创建相同的字符串对象,从而减少内存的占用。
易用性
由于 String 类型是不可变的,因此它的使用非常简单和方便。在程序中,我们可以直接使用 String 对象,而不必担心其值被修改,这样可以减少程序的错误和调试时间。