其他分享
首页 > 其他分享> > [LeetCode] 5. 最长回文子串

[LeetCode] 5. 最长回文子串

作者:互联网

好难呜呜呜呜

方法一:动态规划

class Solution {
public String longestPalindrome(String s) {
    if(s.equals("")) return "";
        String origin=s;
        String reverse=new StringBuffer(s).reverse().toString();
        int length=s.length();
        int[][] arr=new int[length][length];
        int maxLen=0;
        int maxEnd=0;
        for(int i=0;i<length;i++){
            for(int j=0;j<length;j++){
                if(origin.charAt(i)==reverse.charAt(j)){
                    if(i==0||j==0){
                        arr[i][j]=1;
                    }else{
                        arr[i][j]=arr[i - 1][j - 1] + 1;
                    }
                }
            /**********修改的地方*******************/
            if(arr[i][j]>maxLen){
                int beforeRev=length-j-1;
                if (beforeRev + arr[i][j] - 1 == i) { //判断下标是否对应
                    maxLen = arr[i][j];
                    maxEnd = i;
                }
            }
        }
        }
    //return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
    return s.substring(maxEnd-maxLen+1,maxEnd+1);
}
}

 

 方法二:相比于方法一 对arr数组进行了优化,把二维降为一维

class Solution {
public String longestPalindrome(String s) {
    if(s.equals("")) return "";
        String origin=s;
        String reverse=new StringBuffer(s).reverse().toString();
        int length=s.length();
        int[]arr=new int[length];
        int maxLen=0;
        int maxEnd=0;
        for(int i=0;i<length;i++){
            for(int j=length-1;j>=0;j--){
                if(origin.charAt(i)==reverse.charAt(j)){
                    if(i==0||j==0){
                        arr[j]=1;
                    }else{
                        arr[j]=arr[j - 1] + 1;
                    }
                }else{
                    arr[j]=0;
                }
                if(arr[j]>maxLen){
                    int beforeRev=length-j-1;
                    if (beforeRev + arr[j] - 1 == i) { //判断下标是否对应
                        maxLen = arr[j];
                        maxEnd = i;
                    }
                }
            }
        }
    return s.substring(maxEnd-maxLen+1,maxEnd+1);
}
}

 

 没有什么实质性的提高哈。

 

方法三:中心扩散

public class Solution {

    public String longestPalindrome(String s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }
        int maxLen = 1;
        String res = s.substring(0, 1);
        // 中心位置枚举到 len - 2 即可
        for (int i = 0; i < len - 1; i++) {
            String oddStr = centerSpread(s, i, i);
            String evenStr = centerSpread(s, i, i + 1);
            String maxLenStr = oddStr.length() > evenStr.length() ? oddStr : evenStr;
            if (maxLenStr.length() > maxLen) {
                maxLen = maxLenStr.length();
                res = maxLenStr;
            }
        }
        return res;
    }

    private String centerSpread(String s, int left, int right) {
        // left = right 的时候,此时回文中心是一个字符,回文串的长度是奇数
        // right = left + 1 的时候,此时回文中心是一个空隙,回文串的长度是偶数
        int len = s.length();
        int i = left;
        int j = right;
        while (i >= 0 && j < len) {
            if (s.charAt(i) == s.charAt(j)) {
                i--;
                j++;
            } else {
                break;
            }
        }
        // 这里要小心,跳出 while 循环时,恰好满足 s.charAt(i) != s.charAt(j),因此不能取 i,不能取 j
        return s.substring(i + 1, j);
    }
}

 

标签:子串,arr,String,int,maxLen,length,maxEnd,LeetCode,回文
来源: https://www.cnblogs.com/doyi111/p/12852933.html