最长回文子串5

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

题目解析

动态规划:

根据回文串去掉首尾字符后,仍然为回文串。得到状态转移方程:

 S[i:j]=S[i+1:j-1] \wedge (s{_{i}}==s_{j}) &

这个方程的意思就是说S[i+1][j-1]是回文串,且(s_{i}=s_{j})S[i:j]也是回文串,否则S[i:j]不是回文串。

// 动态规划
    public String longestPalindrome(String s){
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        String s1 = "";
        char[] c = s.toCharArray();
        for (int l = 0; l < n; l++){
            for (int i = 0; i + l< n; i++){
                int j = i + l;
                if(l == 0){
                    dp[i][j] = true;
                }
                else if (l == 1){
                    dp[i][j] = (c[i] == c[j]);
                }else{
                    dp[i][j] = (c[i] == c[j] && dp[i + 1][j - 1]);
                }
                if (dp[i][j] && l + 1 > s1.length())
                    s1 = s.substring(i, j + 1);
            }
        }
        return s1;
    }

中心扩展:

找出其中的状态转移链:

P(i, j) \leftarrow P(i+1, j-1) \leftarrow P(i+2, j-2) \leftarrow \cdots \leftarrow \text{某一边界情况}

直到不再为回文串为止。

// 中心扩展法
    public String longe(String s){
        if (s == null || s.length() < 1) return "";
        int star = 0, end = 0;
        for (int i = 0; i < s.length(); i++){
            int length1 = expandAroundCenter(s, i, i);
            int length2 = expandAroundCenter(s, i, i + 1);
            int length = Math.max(length1, length2);
            if(length > end - star){
                star = i - (length - 1) / 2;
                end = i + length / 2;
            }
        }
        return s.substring(star, end + 1);
    }
    public int expandAroundCenter(String s, int left, int right){
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)){
            left--;
            right++;
        }
        return right - left - 1;
    }


 

猜你喜欢

转载自blog.csdn.net/weixin_43222122/article/details/106870262