反转字符串
双指针+元素交换
class Solution {
public void reverseString(char[] s) {
char temp;
int l=0,r=s.length-1;
while(l<r){
temp=s[l];
s[l]=s[r];
s[r]=temp;
l++;
r--;
}
}
}
反转字符串ii
这个题目就是上一个题目的加强版本,我的解法不具有通用性,脑子太死了
找到反转区间的规律,然后对其进行反转;
反转区间的确定+区间反转
class Solution {
public String reverseStr(String s, int k) {
char[] cs = s.toCharArray();
int n = s.length();
for (int l = 0; l < n; l = l + 2 * k) {
int r = l + k - 1;
reverse(cs, l, Math.min(r, n - 1));
}
return String.valueOf(cs);
}
void reverse(char[] cs, int l, int r) {
while (l < r) {
char c = cs[l];
cs[l] = cs[r];
cs[r] = c;
l++; r--;
}
}
}
替换数字
统计数组个数,新建数组进行扩容,给数组进行赋值;
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String s= sc.next();
int len=s.length();
int count=0;
for(int i=0;i<len;i++){
if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
count++;
}
}
char[] res=new char[len+count*5];
for(int j=len-1,k=len+count*5-1;j>=0;j--){
if(s.charAt(j)>='0'&&s.charAt(j)<='9'){
res[k--]='r';
res[k--]='e';
res[k--]='b';
res[k--]='m';
res[k--]='u';
res[k--]='n';
}else{
res[k--]=s.charAt(j);
}
}
System.out.println(new String(res));
}
}
翻转字符串中的单词
双指针找到单词的所在区间,然后存入结果
class Solution {
public String reverseWords(String s) {
s.trim();
int l=s.length()-1,r=s.length()-1;
StringBuilder res=new StringBuilder();
while(l>=0){
while(l>=0&&s.charAt(l)!=' ') l--;
res.append(s.substring(l+1,r+1)+' ');
while(l>=0&&s.charAt(l)==' ') l--;
r=l;
}
return res.toString().trim();
}
}
1.
s是String类型
s.trim() 方法用于移除字符串两端的空白字符,包括空格、制表符、换行符等。这行代码的作用是将变量 s 中存储的字符串两端的空白字符去掉,并将处理后的字符串重新赋值给变量 s。
2.
为什么定义res是StringBuilder类型
在Java中,String 类型是不可变的(immutable),这意味着每次对字符串进行修改时,都会创建一个新的字符串对象。如果在一个循环中不断地对字符串进行修改,比如拼接操作,那么每次修改都会生成一个新的字符串对象,这会导致大量的内存分配和垃圾回收,从而降低程序的性能。
而 StringBuilder 类是可变的(mutable),它提供了一个可变的字符序列,可以在不生成大量临时对象的情况下进行字符串拼接操作。这使得 StringBuilder 成为处理字符串拼接的首选方式,尤其是在循环中进行大量拼接操作时。
3.
res是StringBuilder类型
res.append(...):这是调用 res 字符串的 append 方法,将拼接后的字符串添加到 res 的末尾。
4.
String substring(int beginIndex, int endIndex)
beginIndex:子字符串开始处的索引(包括此索引处的字符)。
endIndex:子字符串结束处的索引(不包括此索引处的字符)。
返回从 beginIndex 到 endIndex - 1 的子字符串。
相当于左闭右开
分裂+倒序
class Solution {
public String reverseWords(String s) {
String[] strs=s.trim().split(" ");
StringBuilder res=new StringBuilder();
for(int i=strs.length-1;i>=0;i--){
if(strs[i].equals("")) continue;
res.append(strs[i]+" ");
}
return res.toString().trim();
}
}
1.
String[] strs=s.trim().split(" ");
split 方法是 Java 中 String 类的一个非常有用的实例方法,它用于将字符串分割成子字符串数组。这个方法根据指定的正则表达式来分割原始字符串。
split 方法需要一个正则表达式作为参数,而正则表达式应该用双引号包围,即 " " 而不是 ' '
" ":匹配空格字符。
",":匹配逗号字符。
[,;]:匹配逗号或分号字符。
2.
if(strs[i].equals("")) continue;
在 Java 中,不能直接将 char 类型与 String 类型进行比较。如果需要比较字符串中的字符,应该将 char 转换为 String,或者直接比较 String 类型的变量。所以是“”双引号,表示空单词
另外,使用 equals 方法比较字符串
3.
方法一和方法二注意细节,方法一是引入字符数组的形式处理,方法二引入字符串数组的形式处理
右旋字符串
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int k = Integer.parseInt(in.nextLine());
String s = in.nextLine();
char[] str=s.toCharArray();
int len=str.length;
rever(str,0,len-1);
rever(str,0,k-1);
rever(str,k,len-1);
System.out.println(new String(str));
}
public static void rever(char[] str,int start,int end){
char temp;
while(start<end){
temp=str[start];
str[start]=str[end];
str[end]=temp;
start++;
end--;
}
}
}
Scanner in = new Scanner(System.in);
int k = Integer.parseInt(in.nextLine());
String s = in.nextLine();
换行读取键入的对象
找出字符串第一个匹配项的下标
巧思妙想,我自己没有想到
class Solution {
public int strStr(String ss, String pp) {
int lenss=ss.length(),lenpp=pp.length();
char[] s=ss.toCharArray(),p=pp.toCharArray();
for(int i=0;i<=lenss-lenpp;i++){
int a=i,b=0;
while(b<lenpp&&s[a]==p[b]){
a++;
b++;
}
if(b==lenpp) return i;
}
return -1;
}
}
这道题可以用KMP算法,我先留个尾巴,回头再来看
重复的子字符串
我发现简单题其实不简单,因为考察的更多是思路;
反而难度的题目其实就是麻烦
这个代码给的太优雅了,我真的佩服
class Solution {
public boolean repeatedSubstringPattern(String s) {
String str = s + s;
return str.substring(1, str.length() - 1).contains(s);
}
}
思路分析:假设字符串s是由s1+s2组成的,s+s后,str就变成了s1+s2+s1+s2;
去掉首尾,破环了首尾的s1和s2,变成了s3+s2+s1+s4;
此时str中间就是s2+s1,如果s是循环字串,也就是s1=s2,所以str中间的s2+s1就和原字符串相等。如果s不是循环字串,s1!=s2,那么s1+s2是不等于s2+s1的,也就是str中间不包含s
主要是要把重复子串全部理解为重复两次,不要考虑太多
另一个思路
也特别奇思妙想
但是我打死都想不出来
class Solution {
public boolean repeatedSubstringPattern(String s) {
int lens = s.length(), i = 0;
while (++i < lens) {
if (lens % i != 0) continue;
if (s.substring(lens - i, lens).equals(s.substring(0, i))) // 判断x是不是基串
if (s.substring(i, lens).equals(s.substring(0, lens - i))) return true; // 判断拿去x后是否相等
}
return false;
}
}