剑指offer05—替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”
思路: 解决此类问题的关键是,java中String 类是不可变的,所以要想改变字符串,可以使用StringBuilder来追加修改,或者将原字符串转换为字符数组再做操作。
法一: 依次遍历字符串s, 将其追加到StringBuilder res中
class Solution {
public String replaceSpace(String s) {
StringBuilder res = new StringBuilder();
for(Character c : s.toCharArray()){
//s.toCharArray将字符串转换为一个新的字符数组
if(c==' '){
res.append("%20");
}
else{
res.append(c);
}
}
return res.toString();
}
}
法二: 创建一个3*length大小的空字符数组,然后依次从头开始遍历字符串s, 遇到空格则将%20三个字符将入字符数组,遇到非空格字符就直接将该字符加入字符数组
class Solution {
public String replaceSpace(String s) {
int length = s.length();
//创建一个新的字符数组
char[] array = new char[length*3];
int size = 0;
for(int i=0; i<length; i++){
char c = s.charAt(i);
if(c == ' '){
array[size++] = '%';
array[size++] = '2';
array[size++] = '0';
}else{
array[size++] = c;
}
}
String result = new String(array,0,size);
return result;
}
}
法三: C++中String是可变的类型,因此可以在不新建字符串的情况下实现原地修改,但java中String是不可变的。所以先将字符串s放到字符数组charArr中来模拟C++中的倒序遍历修改(原地修改):定义两个指针,i指向原字符串的末尾元素,j指向字符数组的末尾元素,当遍历到空格,则将%20赋值给charArr[j-2,j]区间处,j-2;当遍历到非空格时,则将该字符赋值给charArr[j]处;最后i,j指针前移一位继续遍历,直到当i==j时遍历完成。
class Solution {
public String replaceSpace(String s) {
//统计空格数量
int count = 0;
for(int i=0; i<s.length();i++){
if(s.charAt(i)==' '){
count++;
}
}
//根据空格数量和原有字符长度,计算出替换后的字符串长度
int length = count*2+s.length();
char[] charArr = new char[length];
//将字符串转换为字符数组
for(int i=0; i<s.length();i++){
charArr[i] = s.charAt(i);
}
//创建两个指针,一个指向数组末尾,一个指向字符串有效位的末尾,实现原地修改
for(int i=s.length()-1,j=length-1; i<j; i--,j--){
if(charArr[i] != ' '){
charArr[j] = charArr[i];
}else{
charArr[j-2] = '%';
charArr[j-1] = '2';
charArr[j] = '0';
j = j-2;
}
}
//将字符数组charArr转换为String类型返回
return String.valueOf(charArr);
}
}
String, StringBuffer, StringBuilder三者之间关系:
1.String类中使用字符数组保存字符串(private final char value[ ]),由final修饰,故String对象是不可变的
2.StringBuffer和StringBuilder都继承自AbstractStringBuilder类(抽象类),也是使用字符数组保存字符串(char[ ] value),所以这两种对象都是可变的
3.StringBuffer中对方法加了同步锁或者对调用的方法加了同步锁,故StringBuffer线程安全 ,而StringBuilder是非线程安全的
4.如果程序不是多线程的,使用StringBuilder比StringBuffer效率高
三者之间互相转化
剑指offer67 把字符串转换成整数
class Solution {
public int strToInt(String str){
//去除字符串前面和后面的空格
char[] c = str.trim().toCharArray();
if(c.length == 0) return 0;
int res = 0, bndry = Integer.MAX_VALUE/10;//max为2147483647
int sign = 1, i=1;//sign标志符号位,i标志循环起始位
if(c[0] == '-') {
sign = -1;
} else if(c[0] != '+'){
i= 0;
}
//开始循环遍历
for(int j=i; j<c.length; j++){
if(c[j]<'0' || c[j]>'9') break;
if(res>bndry || res==bndry && c[j]>'7'){
return sign == -1? Integer.MIN_VALUE : Integer.MAX_VALUE;
}
res = res*10+(c[j]-'0');
}
return res*sign;
}
}