字符串类型

反转字符串

344. 反转字符串 - 力扣(LeetCode)

这道题比较简单,进行数组索引的方法即可,其实也可以认为是双指针

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public void reverseString(char[] s) {
int length=s.length;
for (int i=0;i<length/2;i++){
char c=s[i];
s[i]=s[length-i-1];
s[length-i-1]=c;
}

}
}

反转字符串II

541. 反转字符串 II - 力扣(LeetCode)

这个知识前面的变种,我们需要找准换算的位置,但是下面这个复杂度就高了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public String reverseStr(String s, int k) {
char[] arr = s.toCharArray();
int length = arr.length;
for (int i = 0; i < length; i = i + k * 2) {
int j = i;
int end;
if (i + k > length) {
end = length;
} else {
end = j + k;
}

while (j < (i + end) / 2) {
int l=end - (j - i) - 1;
//下面对arr【i】到arr【i+k-1】进行反转
char temp = arr[j];
arr[j] = arr[l];
arr[l] = temp;
j++;
}
}
return new String(arr);
}

看一下官方的做法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public String reverseStr(String s, int k) {
int n = s.length();
char[] arr = s.toCharArray();
for (int i = 0; i < n; i += 2 * k) {
reverse(arr, i, Math.min(i + k, n) - 1);
}
return new String(arr);
}

public void reverse(char[] arr, int left, int right) {
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}

}

思路相同,但是相差1ms左右,呃(⊙﹏⊙),可能是中间运算比官方的多插眼

替换空格

剑指 Offer 05. 替换空格 - 力扣(LeetCode)

扩展数组

仔细观察这个替换的规则,使得每一个空格变成原来的三倍,那么现在我们可以创建数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public String replaceSpace(String s) {
char []arr=new char[s.length()*3];
int length=s.length();
int size=0;
for (int i=0;i<length;i++){
char c=s.charAt(i);
if (c==32){
arr[size++]='%';
arr[size++]='2';
arr[size++]='0';
}else {
arr[size++]=c;
}
}
return new String(arr,0,size);
}

}

当然我们也可以调用jdk所提供的方法

1
2
3
4
5
class Solution {
public String replaceSpace(String s) {
return s.replace(" ","%20");
}
}

强制替换

代码随想录 (programmercarl.com)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static String replaceSpace(StringBuffer str) {
if (str == null) {
return null;
}
//选用 StringBuilder 单线程使用,比较快,选不选都行
StringBuilder sb = new StringBuilder();
//使用 sb 逐个复制 str ,碰到空格则替换,否则直接复制
for (int i = 0; i < str.length(); i++) {
//str.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
//if (" ".equals(String.valueOf(str.charAt(i)))){
if (s.charAt(i) == ' ') {
sb.append("%20");
} else {
sb.append(str.charAt(i));
}
}
return sb.toString();
}

双指针法

仔细观察上面的几个代码,我们可以发现他们都是拥有一个目的。因为想要添加东西,就必须扩展原来的字符串空间只不过扩展的思路和方法不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/方式二:双指针法
public String replaceSpace(String s) {
if(s == null || s.length() == 0){
return s;
}
//扩充空间,空格数量2倍
StringBuilder str = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) == ' '){
str.append(" ");
}
}
//若是没有空格直接返回
if(str.length() == 0){
return s;
}
//有空格情况 定义两个指针
int left = s.length() - 1;//左指针:指向原始字符串最后一个位置
s += str.toString();
int right = s.length()-1;//右指针:指向扩展字符串的最后一个位置
char[] chars = s.toCharArray();
while(left>=0){
if(chars[left] == ' '){
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
}else{
chars[right] = chars[left];
}
left--;
right--;
}
return new String(chars);
}