1.トピック
文字列sを考えると、sがで見つかった最長の回文構造部分文字列。あなたは1000秒の最大の長さと仮定することができます。
例1:
入力: "babad"
出力: "BAB"
注: "ABA"は有効な回答です。
例2:
入力: "cbbd"
出力: "BB"
出典:滞在ボタン(LeetCode)
リンクします。https://leetcode-cn.com/problems/longest-palindromic-substring
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。
2.問題解決
- 、あなた自身のDP、比較的低い効率を書きます 時間複雑
- 部分文字列の長さから長さを横断する、特定のノートを参照してください
class Solution {
public:
string longestPalindrome(string s) {
int i, j, len, n = s.size(), maxLen = 0;
if(n <= 1)
return s;
string ans;
vector<vector<int>> dp(n,vector<int>(n,0));
vector<vector<bool>> same(n,vector<bool>(n,false));
//表示区间[i,j]的最大回文长度
for(i = 0; i < n; ++i)
{
dp[i][i] = 1;//单个字符是回文
same[i][i] = true;//区间内字符都一样吗
}
for(len = 1; len < n; ++len)
{
for(i = 0; i < n-len; ++i)
{
if(dp[i][i+len-1])//【i,i+len-1】是回文串
{
if(same[i][i+len-1])//区间内都一样
{ //奇数个字符的回文---> +1变偶数长度(必须区间内全相等)
//偶数个字符的回文---> +1变奇数长度(必须区间内全相等)
if(i-1 >= 0)
{
if(s[i-1]==s[i+len-1])//左边增加1个字符
{
dp[i-1][i+len-1] = 1 + dp[i][i+len-1];
same[i-1][i+len-1] = true;
}
if(s[i-1]==s[i+len])//左右各增加1个
{
if(s[i-1]==s[i])
same[i-1][i+len] = true;
dp[i-1][i+len] = 2 + dp[i][i+len-1];
}
}
if(s[i+len]==s[i])//右边增加1个
{
dp[i][i+len] = 1 + dp[i][i+len-1];
same[i][i+len] = true;
}
}
else//区间[i, i+len-1]内字符不一样,只能+2个字符上来
{
if(i-1>=0 && s[i-1]==s[i+len])
dp[i-1][i+len] = 2 + dp[i][i+len-1];
}
}
if(i-1>=0)
{
if(dp[i-1][i+len-1] > maxLen)
{
maxLen = dp[i-1][i+len-1];
ans = s.substr(i-1,maxLen);
}
if(dp[i-1][i+len] > maxLen)
{
maxLen = dp[i-1][i+len];
ans = s.substr(i-1,maxLen);
}
}
if(dp[i][i+len-1] > maxLen)
{
maxLen = dp[i][i+len-1];
ans = s.substr(i,maxLen);
}
if(dp[i][i+len] > maxLen)
{
maxLen = dp[i][i+len];
ans = s.substr(i,maxLen);
}
}
}
return ans;
}
};
1440ミリ秒202.3メガバイト、ビート5%のCPP