【问题标题】:Convert string to palindrome string with minimum insertions将字符串转换为具有最少插入的回文字符串
【发布时间】:2012-05-30 13:15:46
【问题描述】:

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

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

例如:

1) 阿兹布兹奇兹

需要的插入次数:5 回文串:azbzcezdzeczbza

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

【问题讨论】:

标签: algorithm dynamic-programming palindrome lcs


【解决方案1】:

该解决方案看起来是一个动态规划解决方案。

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

【讨论】:

    【解决方案2】:

    要详细说明 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 开始。现在, 字符串输出 = "";

    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
    

    这样可以更好地阅读吗?

    【讨论】:

    • 谢谢@kyun。但我成功地找出了要插入的数量。我已经指定我需要找到插入后形成的回文字符串?你能给我一个最佳的解决方案吗?提前感谢您。
    • “如果您想了解为什么这是真的,请发表评论”?如果可以的话,你为什么不解释,而不是引诱?
    【解决方案3】:

    S[i, j]代表字符串S的子串,从索引i开始,到索引j结束(含),c[i, j]S[i, j]的最优解。

    显然,c[i, j] = 0 if i &gt;= j

    一般来说,我们有递归:

    【讨论】:

    • 解释重复。
    【解决方案4】:

    简单。见下文:)

            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);
    

    【讨论】:

    • 这个解决方案在大多数情况下都不会给出正确的答案。尝试 OROP ,只需要 1 个字符,即 P 开头,但您的解决方案将给出答案 2。
    【解决方案5】:

    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 );
    

    【讨论】:

      猜你喜欢
      • 2019-08-06
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 2019-02-15
      • 2020-11-05
      • 2019-10-10
      相关资源
      最近更新 更多