day7:字符串part1,反转,替换,翻转
344.反转字符串
字符串也是一种数组,元素在内存中是连续分布
反转字符串与反转链表的相同点:都使用双指针
反转字符串与反转链表的不同点:元素内存分布不同所以方法不同
class Solution {
public void reverseString(char[] s) {
for (int left = 0, right = s.length - 1; left < right; left++, right--) {
char t = s[left];
s[left] = s[right];
s[right] = t;
}
}
}
541.反转字符串2
想要通过固定规律一段一段去处理字符串的时候,要在for循环的表达式上做文章
class Solution {
public String reverseStr(String s, int k) {
char[] str = s.toCharArray();
for (int i = 0; i < str.length; i += 2 * k) {
// 剩余字符多于2k,i += 2k 正常进入下一循环
// 剩余字符少于2k,判断反转结尾位置,少于k全部反转,多于k反转k个
int left = i, right = Math.min(str.length - 1, i + k - 1);
while (left < right) {
char tmp = str[left];
str[left++] = str[right];
str[right--] = tmp;
}
}
return new String(str);
}
}
替换数字
StringBuilder的使用
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) sb.append("number");
else sb.append(c);
}
System.out.println(sb);
}
}
151.翻转字符串里的单词
想一下,我们将整个字符串都反转过来,那么单词的顺序指定是倒序了,只不过单词本身也倒序了,那么再把单词反转一下,单词不就正过来了。
所以解题思路如下:
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
举个例子,源字符串为:"the sky is blue "
- 移除多余空格 : “the sky is blue”
- 字符串反转:“eulb si yks eht”
- 单词反转:“blue is sky the”
这样我们就完成了翻转字符串里的单词。
这道题的重点是删除空格!
不调库版本,练习代码功底
class Solution {
/**
* 不使用Java内置方法实现
* <p>
* 1.去除首尾以及中间多余空格
* 2.反转整个字符串
* 3.反转各个单词
*/
public String reverseWords(String s) {
// System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
private StringBuilder removeSpace(String s) {
// System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
int start = 0;
int end = s.length() - 1;
while (s.charAt(start) == ' ') start++;
while (s.charAt(end) == ' ') end--;
StringBuilder sb = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
// System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
return sb;
}
/**
* 反转字符串指定区间[start, end]的字符
*/
public void reverseString(StringBuilder sb, int start, int end) {
// System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
// System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
}
private void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
使用库函数版本:
class Solution {
public String reverseWords(String s) {
s = s.trim(); // 删除首尾空格
int j = s.length() - 1, i = j;
StringBuilder res = new StringBuilder();
while (i >= 0) {
while (i >= 0 && s.charAt(i) != ' ') i--; // 搜索首个空格
res.append(s.substring(i + 1, j + 1) + " "); // 添加单词
while (i >= 0 && s.charAt(i) == ' ') i--; // 跳过单词间空格
j = i; // j 指向下个单词的尾字符
}
return res.toString().trim(); // 转化为字符串并返回
}
}
右旋转字符串
上题相同的,整体反转+局部反转 的思想
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 - 1); //反转整个字符串
reverseString(chars, 0, n - 1); //反转前一段字符串,此时的字符串首尾尾是0,n - 1
reverseString(chars, n, len - 1); //反转后一段字符串,此时的字符串首尾尾是n,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--;
}
}
}