要在字符串末尾插入的最小字符数,以使其成为回文

时间:2015-03-21 09:18:27

标签: algorithm data-structures

问题是这样的 -

我们必须找到字符串末尾插入的最小字符数,以使其成为回文。

所以,在我努力解决这个问题时,我认为这相当于找到最大的回文子串,这也是字符串的后缀。

我可以很容易地在O(n ^ 2)中做到这一点,但我正在寻找一种可能使用改良KMP的O(n)解决方案。有人请帮我搞清楚。

2 个答案:

答案 0 :(得分:6)

我有一种方法,使用散列作为答案here发布。

您确实也可以使用KMP。您可以为反向字符串计算prefix function,然后从左到右迭代您的初始字符串:

KMP计算函数prefix[i] = longest prefix of the string that is a suffix of string[1..i]

但是,我们想知道the longest suffix of our string that is a prefix of the reversed string。为什么?如果我们有:

15232 => reverse = 23251

然后,作为反向字符串前缀的字符串的最长后缀是232。这是一个回文,它让我们找到你要求的东西,因为如果两个是回文,那么字符串的后缀会与反向字符串的前缀重叠。

你有案例:

prefix[i] = length - i => you can get a palindrome of 
            length 2*prefix[i] centered at i and i+1

prefix[i] = length - i + 1 => you can get a palindrome of
            length 2*prefix[i] - 1 centered at i

prefix[i] < length - i => you can't have a palindrome, ignore this position

因此,计算KMP算法的前缀函数就足够了。

答案 1 :(得分:0)

一个简单的代码,用于插入最少数量的字符并返回它们以使给定的字符串成为pallindrome

#include <bits/stdc++.h>
using namespace std;
bool isPalin(char *s,int x,int l)
{
    for(int i=x,j=l-1;i<j;i++,j--)
        if(s[i]!=s[j])
            return 0;
    return 1;
}
char * f(char *s)
{
    // if s is NULL return NULL
    if(!s)
        return NULL;
    int i,l,j;
    l=strlen(s);
    for(i=0;i<l;i++)
    {
        // check if string is pallindrome from [i...l-1]
        if(isPalin(s,i,l) == 1)
            break;
    }
    // if s is already a pallindrome return NULL
    if(i==0)
        return NULL;
    int k=0;
    // make a char*
    char *ans = new char[i+1];
    for(i-=1;i>=0;i--)
        ans[k++]=s[i];
    ans[k++]='\0';
    return ans;
}

int main() {
    char *a = "wxytabbat";
    cout<<f(a)<<"\n";
    return 0;
}