您的位置:首页 > 其它

LeetCode 5 - Longest Palindromic Substring

2015-07-16 15:42 302 查看
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.


My O(n^3) Code - brute force

class Solution {
public:
string longestPalindrome(string s) {
const int length = s.length();
if (length == 0)
return s;

int* lengths = new int[length];
int startIndex = 0, longestLength = 0;
for (int i = 0; i < length; i++)
{
int minLength;
if (i == 0)
minLength = 1;
else
minLength = min(lengths[i-1] - 2, 1);

int maxLength = length - i;
if (maxLength < longestLength)
break;

for (int lengthIter = minLength; lengthIter <= maxLength; lengthIter++)
{
if (isPalindrome(s.substr(i, lengthIter)))
{
lengths[i] = lengthIter;
if (lengthIter > longestLength)
{
startIndex = i;
longestLength = lengthIter;
}
}
}
}

delete[] lengths;

return s.substr(startIndex, longestLength);
}

inline bool isPalindrome(const string& s)
{
bool flag = true;
int length = s.length();
for (int i = 0; i < length/2; i++)
if (s[i] != s[length-1-i])
{
flag = false;
break;
}

//cout << s << " " << flag << endl;

return flag;
}
};


Runtime: Time Limit Exceeded

 

My O(n^2) Code - dynamic programming

class Solution {
public:
string longestPalindrome(string s) {
const int length = s.length();
if (length <= 1)
return s;

bool dp[length][length];
/*
bool **dp = new bool*[length];
for (int i = 0; i < length; i++)
dp[i] = new bool[length];
*/

int startIndex = 0, longestLength = 1;

for (int i = 0; i < length; i++)
dp[i][i] = true;

for (int i = 0; i < length - 1; i++)
if (s[i] == s[i+1])
{
startIndex = i;
longestLength = 2;
dp[i][i+1] = true;
}
else
dp[i][i+1] = false;

for (int l = 3; l <= length; l++)
{
// Early stop
bool flag = false;
for (int i = 0; i + l - 1 <= length; i++)
if (dp[i][i+l-2])
{
flag = true;
break;
}
if (!flag)
for (int i = 0; i + l - 2 <= length; i++)
if (dp[i][i+l-3])
{
flag = true;
break;
}
if (!flag)
return s.substr(startIndex, longestLength);

for (int i = 0; i + l <= length; i++)
if (s[i] == s[i+l-1] && dp[i+1][i+l-2])
{
startIndex = i;
longestLength = l;
dp[i][i+l-1] = true;
}
else
dp[i][i+l-1] = false;
}

/*
for (int i = 0; i < length; i++)
delete[] dp[i];
delete[] dp;
*/

return s.substr(startIndex, longestLength);
}

inline bool isPalindrome(const string& s)
{
bool flag = true;
int length = s.length();
for (int i = 0; i < length/2; i++)
if (s[i] != s[length-1-i])
{
flag = false;
break;
}

//cout << s << " " << flag << endl;

return flag;
}
};


Runtime: 108 ms

思路:

dp[i][j] 表示子串s[i…j]是否是回文
初始化:dp[i][i] = true (0 <= i <= n-1), dp[i][i+1] = str[i] ==s tr[i+1] (0
<= i <= n-2)

状态转移方程: P[i][j] = P[i+1][j-1] && (str[i]==str[j])


My O(n^2) Code - look back

class Solution {
public:
string longestPalindrome(string s) {
const int length = s.length();
if (length <= 1)
return s;

int startIndex = 0, longestLength = 1;
for (int i = 1; i < length; i++)
{
if (isPalindrome(s.substr(i-longestLength, longestLength+1)))
{
startIndex = i-longestLength;
longestLength++;
}
else if (i-longestLength-1 >= 0 && isPalindrome(s.substr(i-longestLength-1, longestLength+2)))
{
startIndex = i-longestLength-1;
longestLength += 2;
}
}

return s.substr(startIndex, longestLength);
}

inline bool isPalindrome(const string& s)
{
bool flag = true;
int length = s.length();
for (int i = 0; i < length/2; i++)
if (s[i] != s[length-1-i])
{
flag = false;
break;
}

//cout << s << " " << flag << endl;

return flag;
}
};


Runtime: 32 ms

思路:https://leetcode.com/discuss/9948/a-very-brief-o-n-time-o-1-space-solution-ac


My O(n^2) Code - expand

class Solution {
public:
string longestPalindrome(string s) {
const int length = s.length();
if (length <= 1)
return s;

int startIndex = 0, longestLength = 1;
int i = 0;
while (i < length)
{
int j = i - 1, k = i + 1, curLength = 1;

// Escape duplicated characters
while (k < length && s[i] == s[k])
{
k++;
curLength++;
}
i = k;

while (j >= 0 && k < length && s[j] == s[k])
{
j--;
k++;
curLength += 2;
}

if (curLength > longestLength)
{
startIndex = j + 1;
longestLength = curLength;
}
}

return s.substr(startIndex, longestLength);
}
};


Runtime: 8 ms

思路:https://leetcode.com/discuss/32204/simple-c-solution-8ms-13-lines




My O(n) Code - Manacher’s Algorithm

class Solution {
public:
string longestPalindrome(string s) {
const int length = s.length();
if (length <= 1)
return s;

int p[2*length+1];
string ss(2*length+1, '#');
for (int i = 0; i < length; i++)
{
ss[1+2*i] = s[i];
p[1+2*i] = 2;
p[2*i] = 1;
}
p[2*length] = 1;

int startIndex = 0, longestLength = p[0];
for (int i = 1; i < 2*length+1; i++)
{
int j = 2 * startIndex - i;
//cout << "i: " << i << " j: " << j << " idx: " << startIndex << endl;
int curLength;
if (j >= 0 && i < startIndex + longestLength)
if (i + p[j] < startIndex + longestLength)
{
p[i] = p[j];
curLength = p[i];
}
else
curLength = p[j];
else
curLength = p[i];

//cout << "curLength before expand: " << curLength << endl;
while (i - curLength >= 0 && i + curLength < 2 * length + 1 && ss[i+curLength] == ss[i-curLength])
curLength++;
p[i] = curLength;
//cout << "curLength after expand: " << curLength << endl;

if (curLength > longestLength)
{
startIndex = i;
longestLength = curLength;
//cout << "idx: " << startIndex << " longestLength: " << longestLength << endl;
}
}

return s.substr((startIndex-longestLength+1)/2, longestLength-1);
}
};


Runtime: 12 ms

思路:http://www.felix021.com/blog/read.php?2040
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: