344. 反转字符串
建议: 本题是字符串基础题目,就是考察reverse函数的实现,同时也明确一下平时刷题什么时候用库函数,什么时候不用库函数
public static void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
541. 反转字符串II
建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会。
题目链接/文章讲解/视频讲解:代码随想录
重点:
1. 每2k个字符处理一次,所以只要循环的时候 i += (2 * k) 就可以了
2. 所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
public static String reverseStr(String s, int k) {
char[] chars = s.toCharArray();
// 每2k个操作一次
for (int i = 0; i < chars.length; i += 2 * k) {
// 左闭右闭规则
int startIndex = i;
// 这里是判断尾数够不够k个来取决end指针的位置
int endIndex = Math.min(startIndex + k - 1, chars.length - 1);
while (startIndex < endIndex) {
char temp = chars[startIndex];
chars[startIndex] = chars[endIndex];
chars[endIndex] = temp;
startIndex++;
endIndex--;
}
}
return new String(chars);
}
剑指Offer 05.替换空格
建议:对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下。题目链接/文章讲解:代码随想录
重点:
1. 直接使用StringBuilder进行模拟操作
2. 双指针
思路:
1. 单线程,直接使用StringBuilder进行模拟操作,append
2. 双指针:
(1) 先把字符串扩容多空格数量的两倍
(2) 定义两个指针,左指针为原始字符串的最后一个位置,右指针为新字符串的最后一个位置
(3) 如果当前左指针的字符不是空格,则右指针的位置放入这个字符,左右指针同时向前移动一位
(4) 如果当前左指针的字符为空格,则左指针保持不动先,把右指针的字符一个一个向前替换三次,然后左右指针再同时向前移动一位
// 模拟操作
public static String replaceSpace(String s) {
if (s == null) {
return null;
}
StringBuilder stringBuilder = new StringBuilder(s);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
stringBuilder.append("%20");
} else {
stringBuilder.append(s.charAt(i));
}
}
return stringBuilder.toString();
}
// 双指针
public static String replaceSpace(String s) {
if (s == null || s.length() == 0) {
return s;
}
StringBuilder stringBuilder = new StringBuilder();
// 统计要新增多少个字符
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') {
stringBuilder.append(" ");
}
}
// 说明没有空格要替换
if (stringBuilder.length() == 0) {
return s;
}
// 有空格的情况
// left指向原字符串的最后一位
int left = s.length() - 1;
s += stringBuilder.toString();
// right指向替换完毕后字符串的最后一位
int right = s.length() - 1;
char[] chars = s.toCharArray();
while (left >= 0) {
// 如果left所指的字符为空格,right一个一个向前进行替换
if (chars[left] == ' ') {
chars[right--] = '0';
chars[right--] = '2';
chars[right] = '%';
} else {
chars[right] = chars[left];
}
left--;
right--;
}
return new String(chars);
}
151.翻转字符串里的单词
建议:这道题目基本把刚刚做过的字符串操作都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练。
题目链接/文章讲解/视频讲解: 代码随想录重点:
1. 先整体反转再局部反转
思路:
1. 先去除空格,再反转字符串,接着反转单词
public static String reverseWords(String s) {
// 1. 去除首尾以及中间多余空格
StringBuilder stringBuilder = removeSpace(s);
// 2. 反转整个字符串
reverseString(stringBuilder, 0, stringBuilder.length() - 1);
// 3. 反转各个单词
reverseEachWord(stringBuilder);
return stringBuilder.toString();
}
private static StringBuilder removeSpace(String s) {
int start = 0;
int end = s.length() - 1;
// 去头空格
while (s.charAt(start) == ' ') {
start++;
}
// 去尾空格
while (s.charAt(end) == ' ') {
end--;
}
// 去中间空格
StringBuilder stringBuilder = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
// stringBuilder.charAt(stringBuilder.length() - 1) != ' '
// 为的是保证每个单词之间都有一个空格
if (c != ' ' || stringBuilder.charAt(stringBuilder.length() - 1) != ' ') {
stringBuilder.append(c);
}
start++;
}
return stringBuilder;
}
public static void reverseString(StringBuilder stringBuilder, int start, int end) {
// 将整个字符串反转
while (start < end) {
char temp = stringBuilder.charAt(start);
stringBuilder.setCharAt(start, stringBuilder.charAt(end));
stringBuilder.setCharAt(end, temp);
start++;
end--;
}
}
private static void reverseEachWord(StringBuilder stringBuilder) {
// 一个单词一个单词反转
int start = 0;
int end = 1;
int length = stringBuilder.length();
while (start < length) {
while (end < length && stringBuilder.charAt(end) != ' ') {
end++;
}
reverseString(stringBuilder, start, end - 1);
start = end + 1;
end = start + 1;
}
}
剑指Offer58-II.左旋转字符串
建议:题解中的解法如果没接触过的话,应该会想不到题目链接/文章讲解: 代码随想录重点:
1. 先局部反转再整体反转
思路:
1. 反转前n个字符
2. 反转n+1到最后一个字符
3. 反转0到最后一个字符
public static String reverseLeftWords(String s, int n) {
// 1. 反转区间为前n的子串
int len = s.length();
StringBuilder stringBuilder = new StringBuilder(s);
reverseString(stringBuilder, 0, n - 1);
// 2. 反转区间为n到末尾的子串
reverseString(stringBuilder, n, len - 1);
// 3. 反转整个字符串
return stringBuilder.reverse().toString();
}
private static void reverseString(StringBuilder stringBuilder, int start, int end) {
while (start < end) {
char temp = stringBuilder.charAt(start);
stringBuilder.setCharAt(start, stringBuilder.charAt(end));
stringBuilder.setCharAt(end, temp);
start++;
end--;
}
}