反转字符串
344. 反转字符串 - 力扣(LeetCode)
双指针+元素交换
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
541. 反转字符串 II - 力扣(LeetCode)
这个题目就是上一个题目的加强版本,我的解法不具有通用性,脑子太死了
找到反转区间的规律,然后对其进行反转;
反转区间的确定+区间反转
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--;}}
}
替换数字
54. 替换数字(第八期模拟笔试) (kamacoder.com)
统计数组个数,新建数组进行扩容,给数组进行赋值;
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));}}
翻转字符串中的单词
双指针找到单词的所在区间,然后存入结果
151. 反转字符串中的单词 - 力扣(LeetCode)
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.
方法一和方法二注意细节,方法一是引入字符数组的形式处理,方法二引入字符串数组的形式处理
右旋字符串
55. 右旋字符串(第八期模拟笔试) (kamacoder.com)
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算法,我先留个尾巴,回头再来看
28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)
重复的子字符串
我发现简单题其实不简单,因为考察的更多是思路;
反而难度的题目其实就是麻烦
459. 重复的子字符串 - 力扣(LeetCode)
这个代码给的太优雅了,我真的佩服
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
主要是要把重复子串全部理解为重复两次,不要考虑太多
另一个思路
也特别奇思妙想
但是我打死都想不出来
459. 重复的子字符串 - 力扣(LeetCode)
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;}
}