/*
* =====================================================================================
*
* Filename: Longest_Palindromic_Substring.cpp
*
* Description:
*
* Version: 1.0
* Created: 2013年01月10日 17时02分21秒
* Revision: none
* Compiler: gcc
*
* Author: Weidong Yang (cn), ywdong@mail2.sysu.edu.cn
* Company:
*
* =====================================================================================
*/
/*
Given a string S, find the longest palindromic substring in S.
Hint:
First, make sure you understand what a palindrome means. A palindrome
is a string which reads the same in both directions. For example,
“aba” is a palindome, “abc” is not.
*/
#include <cstdio>
#include <cstdlib>
#include <string> // for c++ string class
#include <fstream>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <cstring> // for c str: strcmp,strcat
#include <cassert> // for assert()
#include <climits> // for INT_MIN, INT_MAX;
using namespace std;
bool dp[100][100];
/*
Dynamic programming solution, O(N2) time and O(N2) space:
To improve over the brute force solution from a DP approach,
first think how we can avoid unnecessary re-computation in
validating palindromes. Consider the case “ababa”. If we
already knew that “bab” is a palindrome, it is obvious that
“ababa” must be a palindrome since the two left and right
end letters are the same.
Stated more formally below:
Define P[ i, j ] ← true iff the substring Si … Sj is a
palindrome, otherwise false.
Therefore,
P[ i, j ] ← ( P[ i+1, j-1 ] and Si = Sj )
The base cases are:
P[ i, i ] ← true
P[ i, i+1 ] ← ( Si = Si+1 )
This yields a straight forward DP solution, which we first
initialize the one and two letters palindromes, and work our
way up finding all three letters palindromes, and so on…
*/
char* LongestPalindromeDP(char* str)
{
int n = strlen(str);
if (n < 2)
return str;
int i,j,len;
int begin = 0;
int maxLen = 1;
for (i = 0; i < 100; i++)
for (j = 0; j < 100; j++)
dp[i][j] = false;
for (i = 0; i < n; i++)
dp[i][i] = true;
for (i = 0; i < n - 1; i++)
{
if (str[i] == str[i+1])
{
dp[i][i+1] = true;
begin = i;
maxLen = 2;
}
}
for (len = 3; len <= n; len++)
{
for (i = 0; i <= n - len; i++)
{
j = i + len - 1;
dp[i][j] = dp[i+1][j-1] && (str[i] == str[j]);
if (dp[i][j] && len > maxLen)
{
begin = i;
maxLen = len;
}
}
}
char* res = new char[maxLen+1];
for (i = begin,j = 0; j < maxLen; i++,j++)
res[j] = str[i];
res[j] = '\0';
return res;
}
/*
A simpler approach, O(N2) time and O(1) space:
In fact, we could solve it in O(N2) time without any extra space.
We observe that a palindrome mirrors around its center. Therefore,
a palindrome can be expanded from its center, and there are only
2N-1 such centers.
You might be asking why there are 2N-1 but not N centers? The reason
is the center of a palindrome can be in between two letters. Such
palindromes have even number of letters (such as "abba") and its
center are between the two 'b's.
Since expanding a palindrome around its center could take O(N) time,
the overall complexity is O(N2).
*/
void subString(char* src, char* dest, int begin, int len)
{
if (begin < 0 || len < 0)
{
dest = '\0';
return;
}
int i,j;
for (i = begin, j = 0; j < len; i++, j++)
dest[j] = src[i];
dest[j] = '\0';
return;
}
void ExpandCenter(char* src, char* dest, int left, int right)
{
int l = left;
int r = right;
int n = strlen(src);
while (l >= 0 && r < n && (src[l] == src[r]))
{
l--;
r++;
}
// len = (r-1) - (l+1) + 1;
subString(src, dest, l+1, r-l-1);
return;
}
void LongestPalindromeSimple(char* src, char* dest)
{
int n = strlen(src);
if (n < 2)
{
dest = src;
return;
}
char* tmp_dest = new char[n+1];
unsigned int maxLen = 1;
subString(src, dest, 0, 1);
for(int i = 0; i < n-1; i++)
{
ExpandCenter(src, tmp_dest, i, i);
if (strlen(tmp_dest) > maxLen)
{
maxLen = strlen(tmp_dest);
subString(tmp_dest, dest, 0, maxLen);
}
ExpandCenter(src, tmp_dest, i, i+1);
if (strlen(tmp_dest) > maxLen)
{
maxLen = strlen(tmp_dest);
subString(tmp_dest, dest, 0, maxLen);
}
}
}
int main ( int argc, char *argv[] )
{
char str[] = "3321123";
cout << "Str is : " << str << endl;
char* dest = new char[strlen(str)+1];
char *tmp = LongestPalindromeDP(str);
cout << "In dp solution is :" << tmp << endl;
delete tmp;
LongestPalindromeSimple(str, dest);
cout << "In simple solution is :" << dest << endl;
delete dest;
return 0;
} // ---------- end of function main ----------
最长回文子串
最新推荐文章于 2017-08-03 23:53:39 发布