20230918刷题记录
参考【代码随想录】来刷的。
关键词:字符串、反转字符串
1 剑指Offer 05.替换空格
思路
双指针
- 将字符串转化成字符数组进行处理。
- 将字符串扩容,扩容量为
2 n , n 为字符串中空格的数量 2n,n为字符串中空格的数量 2n,n为字符串中空格的数量 - 使用双指针left、right,
left 指向原字符串中的最后一个字符,用于向前扫描,判断扫描到的字符是不是空格。
right 指向扩容后的字符串的最后一个字符,用于存放新字符。 - left指向的不是空格,则将right指向的值设置为left指向的值;若left指向的是空格,则将right当前指向的即前两位一起设置为%20。然后left,right都向前移动。
为什么要从后往前扫描?
因为如果从前向后扫描,遇到空格时,填充%20会将要用的值覆盖掉,操作麻烦。
class Solution {
public String replaceSpace(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ')
sb.append(" ");
}
if (sb.length() == 0)
return s;
int left = s.length() - 1;
s += sb.toString();
int right = s.length() - 1;
char[] chars = s.toCharArray();
while (left < right) {
if (chars[left] != ' ') {
chars[right] = chars[left];
} else {
chars[right] = '0';
chars[--right] = '2';
chars[--right] = '%';
}
--left;
--right;
}
return new String(chars);
}
}
2 151.翻转字符串里的单词
思路
- 将字符串转化成字符数组进行处理
- 去除字符数组中多余的空格(难点)
- 反转字符数组(easy)
- 对每个单词进行反转
去除多余空格
快慢指针指针
类似这道题目27. 移除元素。
快指针用于扫面整个数组,当快指针指向的值不是要去除的值的时候,将慢指针将指向的值设置为快指针指向的值。
这是27. 移除元素的思路,但本题稍微有点不同,因为
需要保留单词间的一个空格,去除多余的空格。
加一个判断即可,
当当快指针指向的值不是 空格 的时候,判断一下快指针指向的元素的上一个元素是不是空格,如果是,则将慢指针指向的元素设置为空格,然后让慢指针向后移动一步。
反转字符数组
双指针
class Solution {
public String reverseWords(String s) {
char[] chars = s.toCharArray();
// 去除字符数组中多余的空格
int slow = 0;
for (int fast = 0; fast < s.length(); fast++) {
if (chars[fast] != ' ') {
if (slow != 0 && chars[fast - 1] == ' ') chars[slow++] = ' ';
chars[slow] = chars[fast];
slow++;
}
}
// 反转
// slow是去除空格后,数组的逻辑长度
reverse(chars, 0, slow - 1);
// 反转单词
int start = 0;
int i = 0;
while (i < slow) {
while (i < slow && chars[i] != ' ') {
i++;
}
reverse(chars, start, i - 1);
start = i + 1;
i++;
}
return new String(chars, 0, slow);
}
private void reverse(char[] chars, int start, int end) {
while (start < end) {
chars[start] ^= chars[end];
chars[end] ^= chars[start];
chars[start] ^= chars[end];
++start;
--end;
}
}
}
3 剑指Offer58-II.左旋转字符串
力扣题目链接
思路
- 将字符串转化成字符数组进行处理
- 对整个字符数组进行反转
- 对前半部分进行反转
- 对后半部分进行反转
class Solution {
public String reverseLeftWords(String s, int n) {
char[] chars = s.toCharArray();
reverse(chars, 0, chars.length - 1);
reverse(chars, 0, chars.length - n - 1);
reverse(chars, chars.length - n, chars.length - 1);
return new String(chars);
}
private void reverse(char[] chars, int start, int end) {
while (start < end) {
chars[start] ^= chars[end];
chars[end] ^= chars[start];
chars[start] ^= chars[end];
++start;
--end;
}
}
}