LeetCode Longest Palindromic Substring
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.
此题有四种解法:
1、蛮力,对每个子串进行回文判断,时间复杂度O(n^3),空间复杂度O(1),超时
//遍历取得每个字符
for(int i=0 ;i<len ; i++)
{
//对每个字符去其后面的字串
for(int j=0; j<...; j++)
{
//判断每个字串是否为回文
if (isPalindromic())
{
...
}
}
}
2、动态规划
//DP
//思路:添加一个二维数组变量arr[i][j],如果s[i]和s[j]之间的字符组成的子串是回文,则arr[i][j]=true,否则arr[i][j]=false;
//DP最关键的就是设置好规则:若arr[i][j]=true,则arr[i+1][j-1]=true,那么,如果arr[i][j]=true,如果s[i-1]==[j+1],那么arr[i-1][j+1]也是回文串,于是形成递推公式
string longestPalindrome(string s)
{
int iBegin=0, iMaxLen=1;
int iLen = s.length();
bool arr[1001][1001] = {false};
//对于s[i]来说,s[i]单个字符就是回文
for (int i=0; i<iLen; i++)
arr[i][i] = true;
for (int i=0; i<iLen-1; i++)
{
//递推准备工作,判断某个字符与其下一个字符是否能组成回文
if (s[i] == s[i+1])
{
arr[i][i+1] = true;
iBegin = i;
iMaxLen = 2;
}
}
for (int i=2; i<=iLen; i++) //回文可能出现的长度2->iLen
{
for (int j=0; j<iLen-i+1; j++) //j为回文字串的开始位置
{
int k = j+i-1; //k为回文字串的结束位置
if (arr[j+1][k-1]==true && s[j]==s[k])
{
arr[j][k] = true;
iMaxLen = i;
iBegin = j;
}
}
}
return s.substr(iBegin, iMaxLen);
}
3、中间扩展法
就是对给定的字符串S,分别以该字符串S中的每一个字符C为中心,向两边扩展,记录下以字符C为中心的回文子串的长度。但是有一点需要注意的是字符串长度奇偶的问题。
时间复杂度O(n^2),空间复杂度O(1)
<span style="font-family: Arial, Helvetica, sans-serif;">string expands(string& s, int i, int j)</span>
{
int iLen = s.length();
while (i>=0 && j<=iLen-1 && s[i]==s[j])
{
i--;j++;
}
return s.substr(i+1, j-i-1);
}
string longestPalindrome(string s)
{
int iLen = s.length();
if (iLen == 0)
{
return "";
}
string longest = s.substr(0, 1);
for (int i=0; i<iLen; i++)
{
//回文长度为奇数的情况
string s1 = expands(s, i, i);
if (s1.length() > longest.length())
{
longest = s1;
}
//回文长度为偶数的情况
string s2 = expands(s, i, i+1);
if (s2.length() > longest.length())
{
longest= s2;
}
}
return longest;
}
4、网上还有个更好的算法,时间复杂度O(n)