Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd" Output: "bb"
给定一个字符串,求得其最长的回文子串。最初的想法是利用回溯法,求出所有子串,然后比较出长度最长的回文串,类似第131题一样。但是这样复杂度太高,本题只需要求出最长的回文子串即可。列出几个例子后我们可以发现,最长的回文子串的去掉头尾的子串也是回文子串,求取最大回文子串变成了求取最大去掉首尾的回文串问题。这是典型的动态规划题,在剑指offer中,动态规划解决的问题具有以下特点:
- 目标为求问题的最优解;
- 整体的最优解依赖于子问题的最优解;
- 子问题间可能还有相互重叠的更小的子问题;
- 从上往下分析问题(递归),从下往上进行求解(循环)。
对于本题:
我们可以很容易地得到状态转移方程,其中dp中存储的是从i到j这个串是否为回文串的标志:
因此,我们在从下往上求解时,先分析长度为0、1、2的情况,并初始化dp,然后使用长度作为循环变量,不断尝试,得到最大的回文子串,代码记录如下:
class Solution {
public:
//solution with DP
string longestPalindrome(string s) {
if(s.empty())
return "";
int len = s.size();
if(1 == len)
return s;
int max_start_pos = 0;
int max_length = 1;
vector<vector<int>> dp(len, vector<int>(len, 0));
for(int i = 0; i < len; i++)
{
dp[i][i] = 1;
if(i < len - 1)
{
if(s[i] == s[i + 1])
{
dp[i][i + 1] = 1;
max_start_pos = i;
max_length = 2;
}
}
}
for(int sub_len = 3; sub_len <= len; sub_len++)
{
for(int i = 0; i + sub_len - 1 < len; i++)
{
int j = i + sub_len - 1;
if(s[i] == s[j] && dp[i + 1][j - 1] == 1)
{
dp[i][j] = 1;
max_start_pos = i;
max_length = sub_len;
}
}
}
return s.substr(max_start_pos, max_length);
}
};