@[TOC](代码随想录算法训练营第8天 | 344.反转字符串、 541. 反转字符串II、 替换数字(卡码网)、151.翻转字符串里的单词、右旋字符串(卡码网))
344.反转字符串
题目:344.反转字符串
文档讲解:代码随想录-344.反转字符串
视频讲解:哔哩哔哩-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--;
}
}
}
注意:
应该没有特别注意的
541. 反转字符串II
题目:541. 反转字符串II
文档讲解:代码随想录-541. 反转字符串II
视频讲解:哔哩哔哩-541. 反转字符串II
状态/时间:没写出来/三十分钟
思路:
特别注意这个2k 这里,一开始写的非常复杂,又是判断这判断那,2k这里这样写的话,很巧妙,如果在2k内且i + k <= ch.length,直接就是reverStr的i 到i + k - 1
不满足条件就是i, ch.length - 1.
代码:
class Solution {
public String reverseStr(String s, int k) {
char ch[] = s.toCharArray();
for (int i = 0; i < ch.length; i += 2*k) {
if (i + k <= ch.length) {
reverStr(ch, i, i + k - 1);
continue;
}
reverStr(ch, i, ch.length - 1);
}
return new String(ch);
}
public void reverStr(char ch[], int i, int j) {
for (; i < j; i++, j--) {
char temp = ch[i];
ch[i] = ch[j];
ch[j] = temp;
}
}
}
注意:
替换数字(卡码网)
题目:替换数字(卡码网)
文档讲解:代码随想录-替换数字(卡码网)
视频讲解:哔哩哔哩-无
状态/时间:没写出来/三十分钟
思路:
如果是数字的话,判断是数字,然后修改在StringBuilder直接append一个number就好。
代码:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (Character.isDigit(s.charAt(i))) {
sb.append("number");
}else sb.append(s.charAt(i));
}
System.out.println(sb);
}
}
注意:
java 这里直接用StringBuilder就好。
151.翻转字符串里的单词
题目:151.翻转字符串里的单词
文档讲解:代码随想录-151.翻转字符串里的单词
视频讲解:哔哩哔哩-151.翻转字符串里的单词
状态/时间:没写出来/三十分钟
思路:
代码附上卡哥网站的, 注释写的比较清晰,我表达太菜啦
代码:
//解法二:创建新字符数组填充。时间复杂度O(n)
class Solution {
public String reverseWords(String s) {
//源字符数组
char[] initialArr = s.toCharArray();
//新字符数组
char[] newArr = new char[initialArr.length+1];//下面循环添加"单词 ",最终末尾的空格不会返回
int newArrPos = 0;
//i来进行整体对源字符数组从后往前遍历
int i = initialArr.length-1;
while(i>=0){
while(i>=0 && initialArr[i] == ' '){i--;} //跳过空格
//此时i位置是边界或!=空格,先记录当前索引,之后的while用来确定单词的首字母的位置
int right = i;
while(i>=0 && initialArr[i] != ' '){i--;}
//指定区间单词取出(由于i为首字母的前一位,所以这里+1,),取出的每组末尾都带有一个空格
for (int j = i+1; j <= right; j++) {
newArr[newArrPos++] = initialArr[j];
if(j == right){
newArr[newArrPos++] = ' ';//空格
}
}
}
//若是原始字符串没有单词,直接返回空字符串;若是有单词,返回0-末尾空格索引前范围的字符数组(转成String返回)
if(newArrPos == 0){
return "";
}else{
return new String(newArr,0,newArrPos-1);
}
}
}
注意:
细节很多
右旋字符串(卡码网)
题目:右旋字符串(卡码网)
文档讲解:代码随想录-右旋字符串(卡码网)
视频讲解:哔哩哔哩-无
状态/时间:没写出来/三十分钟
思路:
整体反转+局部反转,把字符串分为n和 length - n
思路就是 通过 整体倒叙,把两段子串顺序颠倒,两个段子串里的的字符在倒叙一把,负负得正,这样就不影响子串里面字符的顺序了。
下面也是卡哥的代码
代码:
// 版本二
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = Integer.parseInt(in.nextLine());
String s = in.nextLine();
int len = s.length(); //获取字符串长度
char[] chars = s.toCharArray();
reverseString(chars, 0, len - n - 1); //反转前一段字符串,此时的字符串首尾是0,len - n - 1
reverseString(chars, len - n, len - 1); //反转后一段字符串,此时的字符串首尾是len - n,len - 1
reverseString(chars, 0, len - 1); //反转整个字符串
System.out.println(chars);
}
public static void reverseString(char[] ch, int start, int end) {
//异或法反转字符串,参照题目 344.反转字符串的解释
while (start < end) {
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
start++;
end--;
}
}
}
注意:
我的梦破碎了,哭了哭了。