将弦分成两个最长的回文

时间:2017-06-04 06:14:10

标签: c# algorithm split palindrome subsequence

所以我有这个字符串"nmmaddammhelloollehdertr",如果我们将字符串拆分为x = "nmmaddamm"y = "helloollehdertr",我们可以找到LPS为x = "mmaddamm"y = "helloolleh"。我们知道这是最大的回文,因为x的长度为8,而y的长度为1010 * 8 = 80

我通过使用具有Longest Palindromic Subsequence的动态编程来尝试此问题,注意我需要在枢轴点处分割字符串,从而创建两个具有最长尺寸的字符串。

蛮力的方法是为每个子序列尝试每个单独的回文,这是我的尝试:

using System;

namespace Palindrome
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(GetLongestPalindrome("nmmaddammhelloollehdertr"));
        }

        static int GetLongestPalindrome(string s)
        {
            int longest = 1;
            for (int i = 0; i < s.Length; ++i)
                longest = Math.Max(longest, GetLongestPalindromeHelper(s.Substring(0, i)) * GetLongestPalindromeHelper(s.Substring(i)));
            return longest;
        }

        static int GetLongestPalindromeHelper(string str)
        {
            if (str.Length == 0)
                return 1;

            /*
             * For a str = "madeam"
             *       || 0 | 1 | 2 | 3 | 4 | 5 ||
             *  _____|| m | a | d | e | a | m ||
             * | 0 m || 1 | 1 | 1 | 1 | 1 |_5_||
             * | 1 a || 0 | 1 | 1 | 1 |_3_| 3 ||
             * | 2 d || 0 | 0 |_1_| 1 | 1 | 1 ||
             * | 3 e || 0 | 0 | 0 | 1 | 1 | 1 ||
             * | 4 a || 0 | 0 | 0 | 0 | 1 | 1 ||
             * | 5 m || 0 | 0 | 0 | 0 | 0 | 1 ||
             * 
             */
            int[,] matrix = new int[str.Length, str.Length];

            // i -> row
            // j -> column
            // windowSize -> the numbers of chars in the window

            // each character is a palindrome with a length 1
            for (int i = 0; i < str.Length; ++i)
                matrix[i, i] = 1;

            // we handled windowSize 1, so we start at 2
            for (int windowSize = 2; windowSize <= str.Length; ++windowSize)
            {
                for (int i = 0, j = windowSize - 1; i < str.Length - windowSize + 1; ++i, j = i + windowSize - 1)
                {
                    if (str[i] == str[j])
                        matrix[i, j] = matrix[i + 1, j - 1] + 2;
                    else
                        matrix[i, j] = Math.Max(matrix[i, j - 1], matrix[i + 1, j]);
                }
            }

            return matrix[0, str.Length - 1];
        }
    }
}

但是,我确信有更好的方法可以做到这一点,但我不知道如何做到这一点。有什么建议?此外,任何人都可以指出我的代码的复杂性是什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以在线性时间内执行 Manacher's Algorithm 并获取所有回文的长度。之后,您可以处理长度以从左侧和右侧获得最大长度,然后通过最后一个循环,您可以得到答案。
总复杂度为 O(n) Manacher算法有许多有用的资源,包括以下链接: good explanationAnimation

align-items-xxx