5. The longest palindrome

Insert picture description here

violence

The second layer loop controls the head and tail of the substring respectively. Then determine whether it is a palindrome

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        if(s.length()<=1) return s;
        int n=1;
        int left=0;
        int right=0;
        for (int i = 0; i <s.length(); i++) {
    
    //起点
            for (int j = i+1; j <s.length(); j++) {
    
    //终点
                if(isH(i,j,s)&&j-i+1>n){
    
    
                    left=i;
                    right=j;
                    n=j-i+1;
                }
            }
        }
        return s.substring(left,right+1);
    }
    private boolean isH(int l,int r,String s){
    
    //判断回文串
        while (l<r){
    
    
            if(s.charAt(l)!=s.charAt(r)) return false;
            l++;
            r--;
        }
        return true;
    }
}

Dynamic programming

The palindrome is still a palindrome after removing the first and last two elements.
P(i,j)=P(i+1,j-1)且s(i)==s(j)

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        if (s.length()<=1) return s;
        int n = 1;
        int left = 0;
        int right = 0;
        boolean dp[][] = new boolean[s.length()][s.length()];
        for (int r = 1; r < s.length(); r++) {
    
    
            for (int l = 0; l < r; l++) {
    
    
                if (s.charAt(r) == s.charAt(l) && (r - l <= 2 || dp[l+1][r-1])) {
    
    
                    dp[l][r]=true;
                    if (r - l + 1>=n) {
    
    
                        n = r - l + 1;
                        left = l;
                        right = r;
                    }
                }
            }
        }

        return s.substring(left, right + 1);
    }
}

Center expansion algorithm

Assuming that each element is the center of the palindrome, the double pointer extends from the center to both sides.
When expanding, this palindrome can be odd or even, and it must be judged separately.

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        if (s.length()<=1) return s;
        int n = 1;
        int left = 0;
        int right = 0;
        for (int i = 0; i < s.length()-1; i++) {
    
    
            int oodlen=expand(s,i,i);
            int evenlen=expand(s,i,i+1);
            if(oodlen>evenlen){
    
    
               if(oodlen>n){
    
    
                   n=oodlen;
                   left=i-n/2;
                   right=i+n/2;
               }
            }else{
    
    
                if(evenlen>n){
    
    
                    n=evenlen;
                    left=i-(n-2)/2;
                    right=i+1+(n-2)/2;
                }
            }

        }
        return s.substring(left,right+1);
    }

    private int expand(String s, int l, int r) {
    
    
        if(s.charAt(l)!=s.charAt(r)) return 1;
        while (l<=r&&l>=0&&r<s.length()){
    
    
            if(s.charAt(l)!=s.charAt(r)) break;
            l--;
            r++;
        }
        return r-l-1;
    }

}

Horse-drawn cart O(n)

On the basis of the center expansion algorithm, the symmetry of palindrome is fully utilized.
The idea of the horse-drawn cart algorithm is to reduce repeated judgments on the basis of center diffusion—record the right boundary and center of the latest and rightmost palindrome substring, then according to the symmetry of the palindrome, the center of the substring is to the right but not The substring to be verified that exceeds the right boundary can be verified with the verified substring to the left of the center of the substring, and the substring to be verified that exceeds the right boundary is subjected to simple matching.

class Solution {
    
    
    public String longestPalindrome(String s) {
    
    
        if(s.length()<=1) return s;
        String sb=newString(s);
        int rightSide=0;
        int rightCenter=0;
        int center=0;
        int maxLen=0;
        int op[]=new int[sb.length()];//记录回文串长度一半
        for (int i = 0; i <sb.length(); i++) {
    
    
            boolean flag=true;//是否中心扩展
            if(i<rightSide){
    
    
                int symmetricalIndex=2*rightCenter-i;//i关于rightCenter的对称点
                op[i]=op[symmetricalIndex];
                if(op[i]+i>rightSide){
    
    //这里需要证明
                    op[i]=rightSide-i;
                }
                if(i+op[i]<rightSide){
    
    
                    flag=false;
                }
                //三种情况
                //1.op[i]+i>rightSide ->  op[i]=rightSide-i;,不许要扩展
                //2.op[i]+i==rightSide ,需要扩展
                //3.op[i]+i<rightSide ->  op[i]=op[symmetricalIndex],不要扩展
            }
            if(flag){
    
    
                while (i-1-op[i]>=0&&i+1+op[i]<sb.length()){
    
    
                    if(sb.charAt(i-1-op[i])==sb.charAt(i+1+op[i])){
    
    
                        op[i]++;
                    }else{
    
    
                        break;
                    }
                }
                //更新最右边界,于是中心也要改变。
                rightSide=i+op[i];
                rightCenter=i;
                if(op[i]>maxLen){
    
    //记录答案
                    maxLen=op[i];
                    center=i;
                }
            }
        }
        StringBuffer ans = new StringBuffer();
        for (int i = center-maxLen+1; i <=center+maxLen; i+=2) {
    
    
            ans.append(sb.charAt(i));
        }
        return ans.toString();

    }

    private String newString(String s) {
    
    
        StringBuffer buffer = new StringBuffer();
        buffer.append("#");
        for (int i = 0; i <s.length(); i++) {
    
    
            buffer.append(s.charAt(i));
            buffer.append("#");
        }
        return buffer.toString();
    }
}

More difficult to understand,
reference from: https://www.jianshu.com/p/116aa58b7d81 WeChat Official Account
-Internet Investigation

Guess you like

Origin blog.csdn.net/qq_43179428/article/details/108466651