5. 最长回文子串 + 动态规划

5. 最长回文子串

LeetCode_5

题目详情

方法一:暴力法(超时)

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        int maxLen = 0;
        String result = "";
        for(int i=0; i<len; i++){
            for(int j=len-1; j>=i; j--){
                int k=i,l=j;
                while(k<=l && s.charAt(k) == s.charAt(l)){
                    k++;l--;
                }
                if(k>=l && j-i+1 >= maxLen){
                    maxLen = Math.max(maxLen, j-i+1);
                    result = s.substring(i, j+1);
                }
            }
        }
        return result;
    }
}

方法二:动态规划法

  1. 对于一个子串而言,如果它是回文串,并且长度大于 22,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串 “ababa”,如果我们已经知道 “bab” 是回文串,那么 “ababa” 一定是回文串,这是因为它的首尾两个字母都是 “a”。
  2. 也就是说,只有 s[i+1:j−1] 是回文串,并且 s 的第 i 和 j 个字母相同时,s[i:j] 才会是回文串。
  3. 在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。
class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        boolean[][] dp = new boolean[len][len];

        String result = "";
        for(int l=0; l<len; l++){//l表示子串的长度,子串的长度从小到大
            for(int i=0; i+l<len; i++){//i表示子串的起始位置
                int j = i+l;
                if(l==0)
                    dp[i][j] = true;
                else if(l==1)
                    dp[i][j] = s.charAt(i) == s.charAt(j);
                else
                    dp[i][j] = (s.charAt(i) == s.charAt(j)) && dp[i+1][j-1];
                if(dp[i][j] && l+1 >= result.length()){
                    result = s.substring(i, j+1);
                }
            }
        }
        return result;
    }
}
class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        // dp[i][j]表示(i, j)的子串是否是回文子串
        boolean[][] dp = new boolean[n][n];
        // dp[i][j] = dp[i+1][j-1];
        String res = "" + s.charAt(0);
        for(int i=0; i<n; i++){
            dp[i][i] = true;
        }
        for(int i=n-1; i>=0; i--){
            for(int j=i+1; j<n; j++){
                if(i + 1 == j){
                    dp[i][j] = s.charAt(i) == s.charAt(j);
                }else{
                    dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i+1][j-1];
                }
                if(dp[i][j] && j-i+1 > res.length()){
                    res = s.substring(i, j+1);
                } 
            }
        }
        return res;
    }
}
posted @ 2021-03-03 19:18  Garrett_Wale  阅读(139)  评论(0编辑  收藏  举报