求给定字符串的最长回文子串

问题描述:求给定字符串的最长回文子串,比如输入字符串 "google”,该字符串的回文子串有"oo"和”goog",因此输出“goog"。

解决思路:反转字符串后求反转的字符串与原字符串的最长公共子串,这个最长的公共子串就是所求的最长回文子串

注意:上面的思路有陷阱,这样求解是错误的。当 S=“abacdfgdcaba”, 那么S’ = “abacdgfdcaba”。 这样S和S‘的最长公共子串是abacd。很明显abacd并不是S的最长回文子串,它甚至连回文都不是。

#include "stdafx.h"
#include 
#include 
#include 
#include 
using namespace std;

string getLongestPaString(string s)
{
    string inv_s = "";
    const char* ss = s.c_str();  
    int len = strlen(ss);  
    if(len==0)  
        return inv_s; 
    inv_s = s;
    for(int i=0;i pa_length;
    int max_pa_length = 0;
    int max_pa_flag   = -1;
    for(int i=0;i max_pa_length)
		{
			max_pa_length = max_tmp;
			max_pa_flag = i;
		}
    }
    string max_pa =s.substr(max_pa_flag,max_pa_length);
    return max_pa;
	
}

int _tmain(int argc, _TCHAR* argv[])
{
	string ss = "wfree";
	string a = getLongestPaString(ss);
	cout<

这是个比较容易理解的思路,但算法的时间复杂度为O(n^3),还有待优化。

注意:上面的算法不能完美得出最长回文子串,原串中含有一个非回文的串的反序串的时候,最长公共子串的解法就是不正确的,留着当个警告吧!

在网上还看到其他几种求一个字符串的最长回文子串的方法,准备抽时间实现看看。

1、最容易想到的就是遍历整个字符串,然后求出以每个字符为中心的最长回文串(要考虑奇数和偶数问题),这样的时间复杂度为O(n^2);

2、还有一种就是用后缀数组的方法,将字符串倒转过来然后接到原字符串的后面构造一个新串,中间用一个原字符串中没出现的字符做分隔符,求原字符串最长回文字串就相当于求新串后缀数组的最长公共前缀了,代码较复杂,时间复杂度为O(nlgn);

3、另一种方法时用manacher算法:这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。



你可能感兴趣的:(面试题)