Leetcode-5-最长回文子串

题目

image.png

和516题很像啊,要连着一起看https://www.jianshu.com/p/d737ee489b95

题解

暴力解
列举所有的子串,判断是否为回文串,保存最长的回文串
超出时间限制

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        // s[i,j] 是不是回文子串
        int len = 1;
        String res = s.substring(0, 1);  
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (solver(s, i, j)) {
                    // len = Math.max(len, (j - i) + 1);
                    if (len < (j-i+1)) {
                        len = j - i + 1;
                        res = s.substring(i, j+1);       // substring
                    }
                }
            }
        }
        return res;
    }
    private boolean solver(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}
题解1
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        // s[i,j] 是不是回文子串
        int len = 1;
        String res = "";  
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (solver(s, i, j)) {
                    // len = Math.max(len, (j - i) + 1);
                    if (len < (j-i+1)) {
                        len = j - i + 1;
                        res = s.substring(i, j+1);       // substring
                    }
                }
            }
        }
        return res;
    }
    private boolean solver(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}

结果


初始化改一下
String res = s.substring(0, 1);
或者

不过,改了之后的解答还是超出时间限制

题解2

dp


image.png

索引问题很麻烦,还是建议申请时用n

// dp[i,j]=dp[i+1,j-1]&&check(i,j)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            dp[i][i] = 1;
        }
        int res = 0;
        int start = 0;
        // 考虑dp[i+1,j-1]的合法性,i+1 0; i--) {     
            for (int j = n; j > i; j--) {
                // dp[i][j] = dp[i+1][j-1] && (s.charAt(i-1) == s.charAt(j-1));
                if (s.charAt(i-1) == s.charAt(j-1)) {     // 注意s的索引和dp的索引不同
                    // 排除dp[i][i+1]的情况
                    if (i < j-2) {
                        dp[i][j] = dp[i+1][j-1];
                    } else {
                        dp[i][j] = 1;
                    }
                }
                if (dp[i][j] == 1) {
                    if (j-i+1 > res) {
                        res = j-i+1;
                        start = i-1;     // 注意s的索引和dp的索引不同
                    }
                }
            }
        }
        return s.substring(start, start + res);      
    }
}

错误


image.png

初始化res=1

// dp[i,j]=dp[i+1,j-1]&&check(i,j)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n < 2) {
            return s;
        }
        int[][] dp = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            dp[i][i] = 1;
        }
        int res = 1;
        int start = 0;
        // 考虑dp[i+1,j-1]的合法性,i+1 0; i--) {     
            for (int j = n; j > i; j--) {
                // dp[i][j] = dp[i+1][j-1] && (s.charAt(i-1) == s.charAt(j-1));
                if (s.charAt(i-1) == s.charAt(j-1)) {     // 注意s的索引和dp的索引不同
                    // 排除dp[i][i+1]的情况
                    if (i < j-2) {
                        dp[i][j] = dp[i+1][j-1];
                    } else {
                        dp[i][j] = 1;
                    }
                }
                if (dp[i][j] == 1) {
                    if (j-i+1 > res) {
                        res = j-i+1;
                        start = i-1;     // 注意s的索引和dp的索引不同
                    }
                }
            }
        }
        return s.substring(start, start + res);      
    }
}
参考题解 (推荐)
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        if (n<2) return s;
        int[][] dp = new int[n][n];
        for (int i=0; i=0; i--){
            for (int j=i+1; jlen)){
                    len = j-i+1;
                    start = i;
                }
            }
        }
        return s.substring(start, start+len);
    }
}
参考题解2
public class Solution {

    public String longestPalindrome(String s) {
        // 特判
        int len = s.length();
        if (len < 2) {
            return s;
        }

        int maxLen = 1;
        int begin = 0;

        // dp[i][j] 表示 s[i, j] 是否是回文串
        boolean[][] dp = new boolean[len][len];
        char[] charArray = s.toCharArray();

        for (int i = 0; i < len; i++) {
            dp[i][i] = true;
        }
        for (int j = 1; j < len; j++) {
            for (int i = 0; i < j; i++) {
                if (charArray[i] != charArray[j]) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }

                // 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置
                if (dp[i][j] && j - i + 1 > maxLen) {
                    maxLen = j - i + 1;
                    begin = i;
                }
            }
        }
        return s.substring(begin, begin + maxLen);
    }
}

参考

https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

你可能感兴趣的:(Leetcode-5-最长回文子串)