字符串相关
文章目录
LeetCode344.反转字符串
简单题原地交换,i与n-1-i作为双指针
代码如下
public void reverseString(char[] s) {
int n = s.length; //从两边往中间交换
char temp;
for (int i = 0; i < n / 2; i++) { //交换n/2次
temp = s[n - 1 - i];
s[n - 1 - i] = s[i];
s[i] = temp;
}
}
LeetCode541. 反转字符串II
思路 :k区间的设定使得边界处理相对复杂
重点 1:每次交换前检查是否有k个每次交换完基于i向后跳2k个
public static String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
int n = chars.length;
int p, q; //双指针
int num=k*2; //每次设定区间
int cir = n / num ; //一共有n/num个区间
char tmp;
for (int i = 0; i <= cir; i++) {//交换趟数
p = i * num; //开始
q = p + k - 1; //结束
if (p >= n) { //越界
break;
}
if (q >= n) { //不足k个
q = n - 1;
}
while (p < q) { //交换
tmp = chars[p];
chars[p++] = chars[q];
chars[q--] = tmp;
}
}
return String.valueOf(chars);
}
剑指Offer 05.替换空格
思路: 每次遇见空格就将之前的加入StringBuilder并添加%20 跳过空格继续执行
public String replaceSpace(String s) {
char[] chars = s.toCharArray(); //将字符串转为字符数组
int n = chars.length;
int j;
StringBuilder sb = new StringBuilder(); //StringBuilder
int cnt = 0;
for (int i = 0; i < n; i++) { //遍历字符数组
if (chars[i] == ' ') { //如果遇到' ' 将' '之前全部添加进StringBuilder
sb.append(chars, i - cnt, cnt); //
sb.append("%20"); //并追加%20
cnt = 0;
continue;
} else if (i == n - 1) { //添加剩余没有' '的
sb.append(chars, i - cnt, cnt + 1);
break;
}
cnt++;
}
return sb.toString();
}
LeetCode151.翻转字符串里的单词
首先左右去空格–>从后向前遍历每次开始做标记遇见空格就将标记的长度加入StringBuilder->
添加一个空格并跳过连续空格
本题重点:1:不使用trim()与subString()手动实现去空格与反转 2:标记为的设定
public static String reverseWords(String s) {
char[] chars = s.toCharArray(); //变为字符串数组
int n = chars.length;
int p=0,q=n-1;
while(chars[p]==' '){p++;} //将左右空格跳出
while(chars[q]==' '){q--;};
StringBuilder sb = new StringBuilder();
int cnt;
for (int i = q+1; i > p; ) { //i从后往前遍历
cnt = 0;
while (i > p && chars[i - 1] != ' ') { //直到空格结束
i--;
cnt++;
}
if (cnt != 0) { //将遍历的字符添加进sb
sb.append(chars, i, cnt);
}
if (i == p) {break;} //如果到头直接跳出循环 不用加空格
while (i>p&&chars[i - 1] == ' ') { //跳过所有空格
i--;
}
sb.append(' '); //加一个空格
}
return sb.toString();
}
剑指Offer58-II.左旋转字符串
经典的左旋转,使用逆序来解决 首先逆序前n个再逆序后len-n个 再次逆序所有
public String reverseLeftWords(String s, int n) {
int len = s.length();
/**
先将前n个数反转 再将后len-n个数反转 最后将所有数反转一次
*/
return new String(reverse(reverse(reverse(s.toCharArray(), 0, n - 1), n, len - 1), 0, len - 1));
}
public char[] reverse(char c[], int i, int j) {//反转字符串
char tmp;
System.out.println(c.length);
while (i < j) {
tmp = c[i];
c[i] = c[j];
c[j] = tmp;
i++;
j--;
}
return c;
}
字符串总结
- 上述的经典字符串题目中,在java中String是不可变量,我们通常通过转成char数组添加进StringBuilder中,字符串的多次局部反转可以实现左旋的操作
- 双指针的方法在字符串中有时也可以代替循环,降低时间复杂度
- 操作字符串时,边界条件的判断处理是重点
- 在查找字符串时,kmp算法将在下一章单独分析