1、反转字符1

题目:

https://leetcode.cn/problems/reverse-string/description/

class Solution {
    public void reverseString(char[] s) {
        int n=s.length;
        if(n==1)
         return;
         int left=0;
         int right=n-1;
for(int i=0;i<n/2;i++){
char temp=s[left];
  s[left++]=s[right];
                s[right--]=temp;
}
    }
}

2、反转字符串2

题目:https://leetcode.cn/problems/reverse-string/description/

代码:

class Solution {
    public String reverseStr(String s, int k) {
        int n=s.length();
        char[] arr=s.toCharArray();
        for(int i=0;i<n;i+=2*k){
            reverse(arr,i,Math.min(i+k,n)-1);
        }
        return new String(arr);
    }

     public void reverse(char[] arr, int left, int right) {
        while(left<right){
            char temp=arr[left];
            arr[left]=arr[right];
            arr[right]=temp;
            left++;
            right--;
        }
     }
}

主要是for循环这里的简化以及 最后的k和length的判断(看是否有k个字符了,不判断的话会移动空字符串)

3、替换数字

题目:https://programmercarl.com/kamacoder/0054.%E6%9B%BF%E6%8D%A2%E6%95%B0%E5%AD%97.html

代码

import java.util.*;

public class Main {
     public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String s = sc.next();
        int n=s.length();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)>='0'&&s.charAt(i)<='9')
                n+=5;
        }
        char[] ch=new char[n];
        for(int i=0;i<s.length();i++){
            ch[i]=s.charAt(i);
        }
        for(int i=n-1,j=s.length()-1;j>=0;j--){
            if(ch[j]>='0'&&ch[j]<='9'){
                ch[i--]='r';
                ch[i--]='e';
                ch[i--]='b';
                ch[i--]='m';
                ch[i--]='u';
                ch[i--]='n';
            }
            else{
                ch[i--]=ch[j];
            }
        }
        System.out.println(ch);
        }
}

双指针

java 字符串不能修改

为什么要从后向前填充,从前向后填充不行么?

从前向后填充就是O(n^2)的算法了,因为每次添加元素都要将添加元素之后的所有元素整体向后移动。

其实很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

这么做有两个好处:

  1. 不用申请新数组。

  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

4、反转字符串中的单词

https://leetcode.cn/problems/reverse-words-in-a-string/description/

代码

class Solution {
    public String reverseWords(String s) {
        s=s.trim();//去除前后多余空格
        List<String> list=Arrays.asList(s.split("\\s+"));//以空格分割
        Collections.reverse(list);//反转
        return String.join(" ",list);//空格拼接
    }
}
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();                    // 转化为字符串并返回
    }
}

5、右旋转字符串

https://kamacoder.com/problempage.php?pid=1065

import java.util.*;

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();  //获取字符串长度
        StringBuilder sb=new StringBuilder();
        char[] arr=s.toCharArray();
        for(int i=len-n;i<len;i++){
            sb.append(arr[i]);
        }
        for(int i=0;i<len-n;i++){
             sb.append(arr[i]);
        }   
        
        System.out.println(sb.toString());
         in.close();  // 关闭 Scanner
        }
}



import java.util.*;

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();  //获取字符串长度
        StringBuilder sb=new StringBuilder();
        char[] arr=s.toCharArray();
        sb.append(s.substring(s.length() - n, s.length()));
        sb.append(s.substring(0, s.length() - n));
        
        System.out.println(sb.toString());
         in.close();  // 关闭 Scanner
        }
}

// 版本一
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--;
        }
    }
}


// 版本二
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 - n - 1);  //反转前一段字符串,此时的字符串首尾是0,len - n - 1
        reverseString(chars, len - n, len - 1);  //反转后一段字符串,此时的字符串首尾是len - n,len - 1
        reverseString(chars, 0, 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--;
        }
    }
}

6、kmp 找出字符串中第一个匹配项的下标

https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/description/

class Solution {
    //前缀表(不减一)Java实现
    public int strStr(String haystack, String needle) {
        if(haystack.length()<needle.length())
            return -1;
        if (needle.length() == 0) return 0;
        int[] next = new int[needle.length()];
        getNext(next,needle);
        int j=0;
        for(int i=0;i<haystack.length();i++){
            while(j>0 &&haystack.charAt(i)!=needle.charAt(j)){
                j=next[j-1];
            }
            if (needle.charAt(j) == haystack.charAt(i)) 
                j++;
            if (j == needle.length()) 
                return i - needle.length() + 1;
        }
        return -1;
        }
    

    public void getNext(int[] next,String needle){
        int j=0;
        next[0]=0;
        for(int i=1;i<needle.length();i++){
            while(j>0 &&needle.charAt(i)!=needle.charAt(j)){
                j=next[j-1];
            }
            if(needle.charAt(i)==needle.charAt(j))
                j++;
            next[i]=j;
        }
    }
}

7、重复的子字符串

https://leetcode.cn/problems/repeated-substring-pattern/description/

解法① kmp匹配

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int[] next=new int[s.length()];
        getNext(next,s);
        int max1=s.length()-next[s.length()-1];
        if(s.length()%max1==0&&next[s.length()-1]!=0)
            return true;
    return  false;
    }

    public  void getNext(int[] next,String s){
        int j=0;
        next[j]=0;
        for(int i=1;i<s.length();i++){
            while(j>0&&s.charAt(i)!=s.charAt(j))
                j=next[j-1];
            if(s.charAt(i)==s.charAt(j))
                j++;
            next[i]=j;
        }
    }
}

解法②

s+s

去除前后字符

看新的字符串 是否包含s

class Solution {
    public boolean repeatedSubstringPattern(String s) {

        return  (s.substring(1, s.length()) + s.substring(0, s.length() - 1)).contains(s);
    
    }

}

s=abc s+s=abcabc

从下标1开始 包含abc的索引是下标3 正好等于s的长度

从第二个字符开始,看是否包含s 且索引是否等于s的长度

class Solution {
    public boolean repeatedSubstringPattern(String s) {

       return (s + s).indexOf(s, 1) != s.length();
    
    }

}