使用最少的插入将字符串转换为回文字符串

时间:2012-05-23 23:30:23

标签: algorithm dynamic-programming palindrome lcs

为了找到将给定字符串转换为回文所需的最小插入次数,我找到了字符串(lcs_string)及其反向的最长公共子序列。因此,要进行的插入次数是length(s) - length(lcs_string)

在知道要插入的次数后,应该采用什么方法来找到等效的回文串?

例如:

1)azbzczdzez

所需的插入次数:5 回文字符串:azbzcezdzeczbza

虽然同一根弦可能存在多个回文弦,但我只想找到一个回文?

5 个答案:

答案 0 :(得分:11)

S[i, j]表示字符串S的子字符串,从索引i开始,以索引j结尾(包括两者),c[i, j]S[i, j]的最佳解决方案。

显然,c[i, j] = 0 if i >= j

一般来说,我们有重复:

enter image description here

答案 1 :(得分:1)

详细说明VenomFangs的答案,有一个简单的动态编程解决方案。请注意,我假设此处允许的唯一操作是插入字符(无删除,更新)。设S是一个由n个字符组成的字符串。对此的简单递归函数P是:

    = P [i+1 .. j-1], if S[i] = S[j] 

P [i..j]

    = min (P[i..j-1], P[i+1..j]) + 1,

如果你想更多解释为什么这是真的,发表评论我会很乐意解释(虽然很容易看到一点点思考)。顺便说一句,这与您使用的LCS功能完全相反,因此验证您的解决方案实际上是最佳的。当然,我完全有可能搞砸了,如果有的话,有人会让我知道!

编辑:要考虑回文本身,可以按照以下方式轻松完成: 如上所述,P [1..n]将为您提供使该字符串成为回文所需的插入次数。一旦建立了上面的二维数组,这就是你如何找到回文:

从i = 1开始,j = n。现在,     string output =“”;

while(i < j)
{
    if (P[i][j] == P[i+1][j-1]) //this happens if no insertions were made at this point
    {
        output = output + S[i];
        i++;
        j--;
    }
    else
    if (P[i][j] == P[i+1][j]) //
    {
        output = output + S[i];
        i++;
    }
    else
    {
        output = S[j] + output;
        j--;
    }
 }
 cout<<output<<reverse(output);
 //You may have to be careful about odd sized palindromes here,
 // I haven't accounted for that, it just needs one simple check

这样可以更好地阅读吗?

答案 2 :(得分:0)

该解决方案看起来是一种动态编程解决方案。

您可以在以下帖子中找到答案:How can I compute the number of characters required to turn a string into a palindrome?

答案 3 :(得分:-1)

O(n)的PHP解决方案

function insertNode(&$arr, $idx, $val) {
    $arr = array_merge(array_slice($arr, 0, $idx), array($val), array_slice($arr, $idx));
}
function createPalindrome($arr, $s, $e) {
    $i = 0;
    while(true) {
        if($s >= $e) {
            break;
        } else if($arr[$s] == $arr[$e]) {
            $s++; $e--; // shrink the queue from both sides 
            continue;
        } else {
            insertNode($arr, $s, $arr[$e]);
            $s++;
        }
    }
    echo implode("", $arr);
}
$arr = array('b', 'e', 'a', 'a', 'c', 'd', 'a', 'r', 'e');
echo createPalindrome ( $arr, 0, count ( $arr ) - 1 );

答案 4 :(得分:-2)

简单。见下文:))

        String pattern = "abcdefghgf";
        boolean isPalindrome = false;
        int i=0,j=pattern.length()-1;
        int mismatchCounter = 0;

        while(i<=j)
        {
            //reverse matching
            if(pattern.charAt(i)== pattern.charAt(j))
                {
                    i++; j--; 
                    isPalindrome = true;
                    continue;
                }

            else if(pattern.charAt(i)!= pattern.charAt(j))
                {
                    i++;
                    mismatchCounter++;
                }


        }
        System.out.println("The pattern string is :"+pattern);
        System.out.println("Minimum number of characters required to make this string a palidnrome : "+mismatchCounter);