字符串

17 阅读1分钟

1. 字符串匹配(KMP)

1.1 重复的子字符串

  • KMP算法详解

KMP 算法详解 - 知乎 (zhihu.com)

  • 解法
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        if(s.equals("")) return false;

        int m = s.length();

        // 将两个s拼接在一起,并且去掉首尾字符
        String txt = s + s;
        txt = txt.substring(1, 2*m-1);

        int n = 2*m - 2;

        // kmp算法,找中间是否出现s
        int[][] dp = new int[m][256];
        dp[0][s.charAt(0)] = 1;
        int X = 0;
        for(int j=1;j<m;j++){
            for(int c='a';c<'z';c++) dp[j][c] = dp[X][c];

            dp[j][s.charAt(j)] = j+1;
            X = dp[X][s.charAt(j)];
        }

        int j = 0;
        for(int i=0;i<n;i++){
            j = dp[j][txt.charAt(i)];
            if(j == m) return true;
        }

        return false;
    }
}

2. 回文子串

2.1 回文子串

class Solution {
    public int countSubstrings(String s) {
       // 中心扩展法
       int n = s.length();
       int ans = n; // 默认一个字符的均为回文串

       // 以一个字符为中心
       for(int i=0;i<n;i++){
           int left = i-1;
           int right = i+1;
           while(left>=0 && right<n && s.charAt(left)==s.charAt(right)){
               left--;
               right++;
               ans++;
           }
       }

       // 以两个字符为中心
       for(int i=0;i<n-1;i++){
           if(s.charAt(i) == s.charAt(i+1)){
               ans++;
               int left = i-1;
               int right = i+2;
               while(left>=0 && right<n && s.charAt(left) == s.charAt(right)){
                    ans++;
                    left--;
                    right++;
               }
           }
       }

       return ans;
    }
}

2.2 最长回文子串

class Solution {
    public String longestPalindrome(String s) {
        // 中心扩展法
        int n = s.length();
        int maxn = -1;   // 最长长度
        String ans = ""; // 答案

        for(int center=0;center<2*n-1;center++){
            int left = center/2;
            int right = left + center%2;
            while(left>=0 && right<n && s.charAt(left)==s.charAt(right)){
                String tmp = s.substring(left, right+1);
                if(tmp.length() > ans.length()) ans = tmp;

                left--;
                right++;
            }
        }

        return ans;
    }
}