相关题目:
● 344.反转字符串
● 541. 反转字符串II
● 卡码网:54.替换数字
● 151.翻转字符串里的单词
● 卡码网:55.右旋转字符串
344.反转字符串—双指针的应用
力扣链接
思路:创建两个指针分别指向头部和尾部,首尾交换后依次往里移动在进行交换,直到两个指针相遇或擦身而过为止
实现过程:
public static void reverseString(char[] s) {
if(s == null ||s.length ==1)return;
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—反转进阶版
力扣链接
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
难点
- 遍历指针的步长定义为多少
- 如何出处理剩余字符长度不足2k或不足k的情况
实现过程
public static String reverseStr(String s, int k) {
if (s.length() == 0 || k == 1) {
return s;
}
char[] cs = s.toCharArray();
//i以2k的速度往前走
for (int i = 0; i < cs.length; i += 2 * k) {
//剩余长度大于k,反转前k个字符
if (cs.length - i >= k) {
//反转前k个字符
reverse(cs, i, i + k - 1);
//剩余字符小于k时,将剩余字符全部反转
} else if (cs.length - i < k) {
reverse(cs, i, cs.length - 1);
}
}
return new String(cs);
}
public static void reverse(char[] chars, int start, int end) {
int left = start;
int right = end;
while(left<right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
卡码网:54.替换数字—String类型数据的更新
难点
如何判断字符为数字
解决方法:判断chars[i] -’0‘是否为0或91或介于0-9之间
实现过程
public static String replaceNumber(String str,String replace){
StringBuffer res = new StringBuffer();
char[] cs = str.toCharArray();
for (int i = 0; i < cs.length; i++) {
if(cs[i]-'0'>= 0 && cs[i]-'0'<=9){
res.append(replace);
}
else{
res.append(cs[i]);
}
}
return res.toString();
}
151.翻转字符串里的单词—去除多余空格是难点
按照卡哥的思路解决的难点:
- 如何去除多余空格,难度系数:5※*
- 为何会使用多次反转达到反转单词顺序的目的
实现过程
//反转符串中 单词 的顺序,并去除字符串中多余的空格
// public static String reverseWords(String s) {
// char[] cs = s.toCharArray();
// //1.去掉多余空格,使用双指针完成
// //2.反正整个字符串
// //3.反转每个单词
// }
1.去掉多余空格,使用双指针完成
public static String removeExtraSpaces(String str) {
int fast = 0;
int slow = 0;
char[] cs = str.toCharArray();
StringBuffer stringB = new StringBuffer();
for (; fast < cs.length; fast++) {
//给每个单词之间加空格,并第一个单词前不加空格
if (slow != 0 && cs[fast] != ' ') {
cs[slow++] = ' ';
}
//不是空格的直接赋给慢指针
while (fast < cs.length && cs[fast] != ' ') {
cs[slow++] = cs[fast++];
}
}
for (int i = 0; i < slow; i++) {
stringB.append(cs[i]);
}
return stringB.toString();
}
- 反转整个字符串
public static String reverseString(String str) {
char[] chars = reverse(str.toCharArray(), 0, str.length() - 1);
return new String(chars);
}
- 反转每个单词
public static String reverseWord(String str){
char[] chars = str.toCharArray();
int start = 0;
for (int i = 0; i <= chars.length; i++) {
if ( i == chars.length||chars[i] == ' ') {
reverse(chars, start, i - 1);
start = i + 1;
}
}
return new String(chars);
}
反转算法:
public static char[] reverse(char[] chars, int start, int end) {
int left = start;
int right = end;
while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
return chars;
}
卡码网:55.右旋转字符串—反转字符串的应用
右旋转字符串
- 先整体反转
- 前一段反转:长度为n
- 后一段反转:长度为len-n
左旋转字符串
- 前一段反转:长度为len-n
- 后一段反转:长度为n
- 整体反转
实现过程
右旋转字符串
public static String rightRotate(String str,int n){
char[] chars = str.toCharArray();
//反转整个字符串
reverse(chars,0,chars.length-1);
//反转前一段,长度为n
reverse(chars,0,n-1);
//反转后一段,长度为len-n
reverse(chars,n,chars.length-1);
return new String(chars);
}
public static void reverse(char[] chars,int start,int end){
int left = start;
int right = end;
while(left<right){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
左旋转字符串
public static String rightRotate(String str,int n){
char[] chars = str.toCharArray();
//反转前一段,长度为len-n
reverse(chars,0,len-n-1);
//反转后一段,长度为n
reverse(chars,len-n,chars.length-1);
//反转整个字符串
reverse(chars,0,chars.length-1);
return new String(chars);
}
public static void reverse(char[] chars,int start,int end){
int left = start;
int right = end;
while(left<right){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}
}
总结:
字符串交换题目:双指针进行交换,
交换的进阶版:首先看多次交换是否可以得到结果
其中有些题目需要移除某些元素:可借助数组章节的leecode—移除元素一题的思想进行解决