字符串的相关练习
文章目录
1.反转字符串
思路
1.从题中可以知道实现字符串的翻转
2.那么第一个字符和最后一个字符交换位置
3.第二个和倒数第二个字符交换位置
4.重复交换操作
5.直到交换完成,返回字符串
代码实现
package com.algo.string;
public class Algo344 {
public void reverseString(char[] s) {
//定义两个指针
int left = 0;
int right = s.length - 1;
char temp ;//最为临时交换值
while (left < right) {
temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
2.反转字符串II
力扣:541. 反转字符串 II - 力扣(Leetcode)
思路
1.题目概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
2.先将字符串转换成字符数组
3.for循环,开始遍历
4.判断尾数够不够k个来取决end指针的位置
5.翻转操作
代码实现
package com.algo.string;
public class Algo541 {
public String reverseStr(String s, int k) {
//题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i += 2 * k) {
int start = i;
//这里是判断尾数够不够k个来取决end指针的位置
int end = Math.min(ch.length-1, start+k-1);
while(start < end){
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
}
return String.valueOf(ch);
}
}
3.替换空格
力扣:剑指 Offer 05. 替换空格 - 力扣(Leetcode)
思路
1.将原始字符串复制到新的字符串
2.当碰见空格时,将空格替换成%20
3.没碰见空格就将元素添加到新的数组
3.当遍历完原始数组后,就完成了空格替换
代码实现
package com.algo.string;
public class AlgoOffer05 {
public String replaceSpace(String s) {
if(s==null){
return null;
}
//采用复制的思想 如果遇到' ' 则替换为%20 否则照搬
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)==' '){
//将空格替换成%20
stringBuilder.append("%20");
}else{
//将元素添加到新的数组
stringBuilder.append(s.charAt(i));
}
}
return stringBuilder.toString();
}
}
4.翻转字符串里的单词
力扣:151. 反转字符串中的单词 - 力扣(Leetcode)
思路
1.处理字符串里的空格
1)翻转字符串里的单词,先将首尾空格除掉
2)当去掉空格后,字符串的首尾位置就确定了
3)再将字符串中多个空格合并成一个空格
2.将字符串复制StringBuilder进行操作
3.翻转字符串
1)将第一个字符和最后一个字符交换位置
2)将第二个字符和倒数第二个字符交换位置
3)重复操作,知道全部交换位置,就将字符串翻转了
4.翻转之后再将单词再次翻转就完成了翻转字符串里的单词
1)先找到空格,将空格前的子字符串翻转
2)往复操作,直到全部翻转
代码实现
package com.algo.string;
public class Algo151 {
public String reverseWords(String s) {
//先取出字符串首尾空格
int start = 0;
int end = s.length()-1;
while (s.charAt(start)==' '){
start++;
}
while (s.charAt(end)==' '){
end--;
}
//当跳出两个循环后 就是字符串起始位置和结束位置
StringBuilder stringBuilder = new StringBuilder();
//将字符串复制
for (;start<=end;start++){
if(s.charAt(start)==' '){
//将中间出现的空格合并成一个空格
while (s.charAt(start)==' '){
start++;
}
stringBuilder.append(" ");
}
stringBuilder.append(s.charAt(start));
}
//翻转字符串
start = 0;
end = stringBuilder.length()-1;
while (start<=end){
char ch = stringBuilder.charAt(start);
stringBuilder.setCharAt(start, stringBuilder.charAt(end));
stringBuilder.setCharAt(end,ch);
start++;
end--;
}
//翻转以后 再翻转指定区间的字符串 即翻转单词
end= 0;
start = 0;
//当指针没到最后就一直循环
while (end<stringBuilder.length()){
//如果指针指向' ' 表明第一个单词的结尾就在指针前一个位置 当指针指向最后一个单词的最后一个字符时也进入
if(stringBuilder.charAt(end)==' '||end==stringBuilder.length()-1){
int start1 = start;//start1永远指向单词的首字母
int end1 = end-1;
//当指针指向最后一个字符就不能将end1指向前一个字符了 而是让end1=end 即end1永远指向单词的尾字母
if(end==stringBuilder.length()-1){
end1 = end;
}
while (start1<end1){
char ch = stringBuilder.charAt(start1);
stringBuilder.setCharAt(start1, stringBuilder.charAt(end1));
stringBuilder.setCharAt(end1,ch);
start1++;
end1--;
}
//跳出循环后 start移到新的单词的首字母
start = end+1;
}
end++;
}
return stringBuilder.toString();
}
}
5.左旋转字符串
力扣:剑指 Offer 58 - II. 左旋转字符串 - 力扣(Leetcode)
思路
1.先将前n个字符串翻转
2.再将除了前n个字符串翻转
3.再将整个字符串翻转
代码实现
package com.algo.string;
public class AlgoOffer58 {
public String reverseLeftWords(String s, int n) {
//先翻转前n个元素
//定义一个指针
int left = 0;
StringBuilder stringBuilder = new StringBuilder(s);
char ch ;//定义一个交换值的临时保存
int m = n;
while (left<n){
ch = s.charAt(left);
stringBuilder.setCharAt(left,s.charAt(m-1));
stringBuilder.setCharAt(m-1, ch);
left++;
m--;
}
//跳出循环表明前n个字符已完成翻转
//翻转后面的字符
left = n;
m = s.length()-1;
while (left<s.length()){
ch = s.charAt(left);
stringBuilder.setCharAt(left,s.charAt(m));
stringBuilder.setCharAt(m, ch);
left++;
m--;
}
//翻转整个字符
left = 0;
m = s.length()-1;
while (left<=m){
ch = stringBuilder.charAt(left);
stringBuilder.setCharAt(left,stringBuilder.charAt(m));
stringBuilder.setCharAt(m, ch);
left++;
m--;
}
return stringBuilder.toString();
}
}
6.实现strStr()
力扣:28. 找出字符串中第一个匹配项的下标 - 力扣(Leetcode)
思路
1.字符串匹配,先判断是否有效,无效返回-1
2.给haystack定义两个指针 第一个指针一直指向第一个匹配项的下标
3.第二个指针当出现相同匹配项时,第二个指针向后移
4.给needle定义一个指针 当出现相同匹配项时,指针后移
5.当匹配项不同时,将needle的指针重新指针第一个字符 同时haystack的第一个指针向后移
6.再次重新判断
7.当子字符串匹配成功,就将haystack所指位置返回
代码实现
package com.algo.string;
public class Algo28 {
public int strStr(String haystack, String needle) {
if(needle.length()>haystack.length()){
return -1;
}
//给haystack定义两个指针
int lefth = 0;
int righth = 0;
//给needle定义一个指针
int leftn = 0;
int res = -1;//存放结果
while (lefth<haystack.length()){
if(haystack.charAt(lefth)==needle.charAt(leftn)){//当出现needle首个字符时进入循环
righth = lefth;//将lefth赋值给righth,然后靠righth向后遍历 继续找
while (leftn<needle.length()&&righth<haystack.length()&&haystack.charAt(righth)==needle.charAt(leftn)){
//leftn<needle.length()&&righth<haystack.length()防止字符串越界
//haystack.charAt(righth)==needle.charAt(leftn) 查找条件 匹配字符相等就继续判断下一个
righth++;
leftn++;
}
if(leftn==needle.length()){//跳出循环有两种情况 第一种就是needle数组索引到最后 即找到位置
res = lefth;//将开始位置赋给res
break;
}else{
leftn=0;//重置
}
}
lefth++;//向后移
}
return res;
}
}
7.重复的子字符串
力扣:459. 重复的子字符串 - 力扣(Leetcode)
思路
1.假设字符串s是由s1+s2组成的,s+s后
2.str就变成了s1+s2+s1+s2,去掉首尾,破环了首尾的s1和s2
3.变成了s3+s2+s1+s4,此时str中间就是s2+s1,如果s是循环字串
4.也就是s1=s2,所以str中间的s2+s1就和原字符串相等。
5.如果s不是循环字串, s1!=s2,那么s1+s2是不等于s2+s1的,也就是str中间不包含s
代码实现
package com.algo.string;
public class Algo459 {
public boolean repeatedSubstringPattern(String s) {
//给定一个非空的字符串 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
String str = s+s;
str = str.substring(1,str.length() - 1);
return str.contains(s);
}
}