学习目标:
- 344.反转字符串
- 541. 反转字符串II
- 剑指Offer 05.替换空格
- 151.翻转字符串里的单词
解题记录:
344.反转字符串
class Solution {
public 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--;
*/
//法二
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
541. 反转字符串II
class Solution {
public String reverseStr(String s, int k) {
//字符串转字节数组
char[] ch = s.toCharArray();
// 1. 每隔 2k 个字符的前 k 个字符进行反转
for(int i = 0; i < ch.length; i += 2*k) {
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if(i + k <= ch.length) {
reverse(ch, i, i + k - 1);
continue;
}
// 3. 剩余字符少于 k 个,则将剩余字符全部反转
reverse(ch, i, ch.length - 1);
}
return new String(ch);//字符数组转为字符串返回
}
// 定义翻转函数
public void reverse(char[] s, int i, int k) {
while(k > i) {
char temp = s[i];
s[i] = s[k];
s[k] = temp;
i++;
k--;
}
}
}
剑指Offer 05.替换空格
方法一
class Solution {
public String replaceSpace(String s) {
//方法一:使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
if(s == null) {
return null;
}
//选用 StringBuilder 单线程使用,比较快,选不选都行
StringBuilder sb = new StringBuilder();
//使用 sb 逐个复制 s ,碰到空格则替换,否则直接复制
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == ' ') {
sb.append("%20");
} else {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
}
方法二:双指针
class Solution {
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[] ch = s.toCharArray();
for(;left >= 0; left--) {
if(ch[left] == ' ') {
ch[right] = '0';
ch[right - 1] = '2';
ch[right - 2] = '%';
right -= 3;
} else {
ch[right] = ch[left];
right--;
}
}
return new String(ch);
}
}
151.翻转字符串里的单词
class Solution {
public String reverseWords(String s) {
char[] ch = s.toCharArray();
// 1.去除首尾以及中间多余空格
ch = removeExtraSpaces(ch);
// 2.反转整个字符串
reverse(ch, 0, ch.length - 1);
// 3.反转各个单词
reverseEachWord(ch);
return new String(ch);
}
//1.用 快慢指针 去除首尾以及中间多余空格,可参考数组元素移除的题解
public char[] removeExtraSpaces(char[] chars) {
int slow = 0;
for(int fast = 0; fast < chars.length; fast++) {
//先用 fast 移除所有空格
if(chars[fast] != ' ') {
//再用 slow 加空格。除第一个单词外,单词末尾要加空格
if(slow != 0) {
chars[slow++] = ' ';
}
//fast 遇到空格或遍历到字符串末尾,就证明遍历完一个单词了
while(fast < chars.length && chars[fast] != ' ') {
chars[slow++] = chars[fast++];
}
}
}
//相当于 c++ 里的 resize()
char[] newChars = new char[slow];
System.arraycopy(chars, 0, newChars, 0, slow);
return newChars;
}
//双指针实现指定范围内字符串反转,可参考字符串反转题解
public void reverse(char[] chars, int left, int right) {
while(left < right) {
chars[left] ^= chars[right];
chars[right] ^= chars[left];
chars[left] ^= chars[right];
left++;
right--;
}
}
//3.单词反转
public void reverseEachWord(char[] chars) {
int start = 0;
for(int end = 0; end <= chars.length - 1; end++) {
if(end == chars.length - 1 || chars[end + 1] == ' ') {
reverse(chars, start, end);
start = end + 2;
}
}
}
}
学习成果:
- 344.反转字符串
- 541. 反转字符串II
- 剑指Offer 05.替换空格
- 151.翻转字符串里的单词