5. 最长回文子串

https://leetcode-cn.com/problems/longest-palindromic-substring/

解法一:暴力

两个for循环,外层i遍历每个字符,然后内层j从i分别向两侧出发,找两头是否相等,不相等就退出循环。每次找到一个回文串,求长度,并记录首尾位置。

class Solution {
public:
    string longestPalindrome(string s) {
        int maxLen = 0;
        int n = s.length();
        int start = 0, end = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; i-j >= 0 && i+j < n && s[i+j] == s[i-j]; j++) {  //回文长度为奇
                if (2*j+1 > maxLen) {  // len = (i+j)-(i-j)+1 = 2*j+1
                    start = i-j;
                    end = i+j;
                    maxLen = 2*j+1;
                }
            }
            for (int j = 0; i-1-j >= 0 && i+j < n && s[i-1-j] == s[i+j]; j++) {  //回文长度为偶
                if(2*j+2 > maxLen) {  // len = (i+j)-(i-1-j)+1 = 2*j+2
                    start = i-1-j;
                    end = i+j;
                    maxLen = 2*j+2;
                }
            }
        }
        return s.substr(start, end-start+1);
    }
};

解法二:DP

dp(i, j) represents whether s(i ... j) can form a palindromic substring, dp(i, j) is true when s(i) equals to s(j) and s(i+1 ... j-1) is a palindromic substring. When we found a palindrome, check if it’s the longest one. Time complexity O(n^2). 需要注意的是构造初始解时,i是从n-1开始,为何?

看下图可知,对于串“aaaa”,由于i<=j,因此矩阵只有上三角。初始化斜对角全为1(因为单个字符必为回文串),第二条对角线根据是否有i==j决定(两个字符只有a==b才为回文)。其余每个元素(i, j)根据其左下方元素(i+1, j-1)决定。

实际上j由大到小也可以,因为填充方式是从下往上,因此只要保证i从大到小即可,j顺序可以随意,下一层都已经填完

然而运行时dp比暴力慢许多,不知为何

最后更新于