最长回文子串

最长回文子串

题目描述:

给你一个字符串s,找到s中最长的回文子串

示例1:

输入:s = “babad”

输出:“bab”

示例2:

输入:s = ”cbbd“

输出:“bb”

tips:

1 <= s.length <= 100

s仅由数字和英文字母组成

题解:

方法一:动态规划

对于回文串s,在s左右两边加上相同的字符得到s‘,则s’仍然为回文串,由此可以建立转移方程:

\[if(s[i] == s[j]\ \&\& \ s[i + 1......j - 1] \ is \ pal) \\ dp[i][j] = dp[i + 1][j - 1] + 2 \]

其中\(dp[i][j]\)代表i到j间是否是一个回文串,是则记录长度,不是为0。

处理边界

当字符串长度为1时,必为回文串\(\rightarrow \ dp[i][i] = 1\)

当字符串长度为2且两字符相同时,必为回文串\(s[i] = s[i + 1] \ \rightarrow \ dp[i][i + 1] = 2\)

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.length();
        if(n < 2) return s;
        vector<vector<int>> dp(n, vector<int>(n));
        int ans = 1, be = 0;
        for(int i = 0; i < n; ++i) dp[i][i] = 1;
        for(int l = 2; l <= n; ++l) {
            for(int i = 0; i < n; ++i) {
                int j = i + l - 1;
                if(j >= n) break;
                if(s[i] != s[j]) dp[i][j] = 0;
                else {
                    if(l == 2) {
                        dp[i][j] = 2;
                    }
                    else {
                        if(dp[i + 1][j - 1]) dp[i][j] = dp[i + 1][j - 1] + 2;
                    }
                    if(dp[i][j] > ans) {
                        ans = dp[i][j];
                        be = i;
                    }
                }
            }
        }
        return s.substr(be, ans);
    }
};

方法二:中心扩展法

从方法一状态转移方程可以看出,每次回文子串长度增加情况唯一:

\(dp[i][j] + 2 \leftarrow dp[i + 1][j - 1] \leftarrow ....边界情况\)

从边界情况开始扩展,最后也可以得到最长回文子串。

class Solution {
public:
    string longestPalindrome(string s) {
        int be = 0, maxLen = 1;
        int n = s.length();
        for(int i = 0; i < n; ++i) {
            int l = i, r = i;
            int len = -1;
            while(l >= 0 && r < n && s[l] == s[r]) {
                len += 2;
                l--;
                r++;
            }
            if(len > maxLen) {
                maxLen = len;
                be = l + 1;
            }
            len = 0;
            l = i, r = i + 1;
            while(l >= 0 && r < n && s[l] == s[r]) {
                len += 2;
                l--; r++;
            }
            if(len > maxLen) {
                maxLen = len;
                be = l + 1;
            }
        }
        return s.substr(be, maxLen);
    }
};

方法三:Manancher(马拉车算法)

-------------待更----------------

posted @ 2022-03-17 10:26  落水清心  阅读(30)  评论(0编辑  收藏  举报