问题描述
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
给定一个字符串S
,找到最长的回文子串(S
的长度最长为1000且一定存在一个唯一的最长子串)
# 回文的意思:
abbbba # 就是一个回文字符串
cabbbbaf # 最长的回文字符串就是abbbba
问题分析
动态规划解题:
P(i,j)
表示从i
到j
的子串是否为回文字符串,true
为是,false
为否;那么P(i, j) = true
,意味着S[i] == S[j]
,也一定意味着 p(i+1, j-1)=true
,比如:
回文字符串:abcddcba
中,P(0,7) = true
,有 P(0+1, 7-1) = P(1,6) = true
,再往下一层也还是true
,这样就可以得出状态转移方程了:
P(i,j) = P(i+1, j-1) ,S[i] = S[j]
P(i,i) = true
有了上述两个方程,解字符串长度为单数的回文子字符串是够了,比如 aabaa
这种形式的,但是 aabbaa
这种偶数型的就不行了,所以,还需要下面一个方程:
P(i, i+1) = true,S[i] = S[i+1]
P(i,i)和P(i, i+1)都相当于递归的终止条件,需要提前算出。
代码
class Solution {
public:
string longestPalindrome(string s) {
int length = s.size();
if(length < 2) return s;
// 状态表
bool P[1000][1000]={false};
int start = 0; // 最长回文字符串开始字符的索引
int maxLength = 0; // 最长回文字符串的长度
for(int i=0; i < length; i++) {
// 第 i 个 到 i 个必然是回文的
P[i][i] = true;
// 判断相邻两数是否相等,若相等,便是回文字符串的初始条件
if(i<length-1&&s[i] == s[i+1]) {
P[i][i+1] = true;
start = i;
maxLength = 2;
}
}
for(int subLen = 3; subLen <= length; subLen++) {
for(int i = 0; i <= length - subLen; i++) {
int j = i + subLen - 1;
if(P[i+1][j-1] && s[i] == s[j]){
P[i][j] = true;
maxLength = subLen;
start = i;
}
}
}
return s.substr(start, maxLength);
}
};