我们如何通过重新排列字符串中的字符来获得最大数量的回文子串?

Posted

技术标签:

【中文标题】我们如何通过重新排列字符串中的字符来获得最大数量的回文子串?【英文标题】:How can we make maximum number of palindromic substrings by rearranging the characters in a string? 【发布时间】:2018-10-17 15:26:31 【问题描述】:

一个字符串称为另一个字符串的子字符串,如果它可以通过从该字符串的开头和结尾删除一些(可能为零)个字符来从该字符串中获得。

例如,abcabc 是字符串 abc 的子字符串,而 acd 不是。

让我们将字符串的回文计数定义为它的回文子串的数量。

例如,字符串aaa 的回文计数是 6,因为它的所有子字符串都是回文。并且字符串abc 的回文数是 3,因为只有它的长度为 1 的子字符串是回文数。

那么,再举两个例子:

    如果字符串 -> oolol

    answer = ololo,  9 substrings can be formed
    'o', 'l', 'o', 'l', 'o', 'olo', 'lol', 'olo', 'ololo'
    

    如果字符串 -> gagadbcgghhchbdg

    answer = abccbaghghghgdfd, 29 substrings can be formed
    

给你一个字符串 s。您可以任意重新排列其字符。您的目标是获得一个具有最大可能回文计数值的字符串。

【问题讨论】:

不应该自己做作业吗? 我已经尝试了很多,但无法提出解决方案 @PrateekAgarwal 我的方法能解决你的问题吗? @nlex 我已经编辑了我的问题,我必须找到一个重排,其中回文计数最大。我不想检查所有可能的回文重排。我只是为了从回文计数最大的 sring 重新排列。如果您对此有解决方案,请发表评论。顺便感谢您之前的方法 @Neo,我已经在我的回答中提出了最佳解决方案。我已经对其进行了编辑以使其更加详细。请看一下,如果仍有疑问,请告诉我。 【参考方案1】:

产生最大回文数的字符串的最佳可能重新排列可能是sorted string。以字符串abcabc 为例,让n 表示一般字符串的大小。

我们可以重新排列字符串以形成回文abc|cba,这将产生长度为 n(所有单个字符)+ n/2(通过反射点挑选子串)+ 在任一处都存在回文的情况反射点,在本例中为 0。

我们还可以重新排列字符串以形成 (aa)(bb)(cc) 形式的回文对,这将产生 n(单个字符)+ n/2(成对子字符串)+ 其他可能的回文子字符串回文。

同样地,也可以形成一个 3 对回文数 (aba)(cbc),在这种情况下,回文数的数量将是 n + n/3 + ..

显然,随着我们形成更多的 m 对回文,回文子串的数量将会下降。因此,我们需要考虑案例 I 和案例 II。在这两者中,最好通过增加同时出现的相等字符的密度来最大化情况 II 的 other .. 情况,这是排序字符串中的情况。因此,排序后的字符串应该会产生最佳答案。

因此对于您的情况,oolol -> llooo 将给出 9 的最佳结果,gagadbcgghhchbdg -> aabbccddfgggghhh 也将给出 29 的最佳结果。您可以使用以下代码检查任何字符串:https://ideone.com/mMu2tq

def ispalin(s):
    return (s == s[::-1])

def cpalin(s):
    c = 0
    for i in range(len(s)):
        for j in range(i, len(s)):
            if ispalin(s[i:j + 1]):
                c += 1
    return c

print(cpalin(''.join(sorted("abccbaghghghgdfd"))))
print(cpalin(''.join(sorted("oolol"))))

【讨论】:

以上是关于我们如何通过重新排列字符串中的字符来获得最大数量的回文子串?的主要内容,如果未能解决你的问题,请参考以下文章

计数和迭代序列的排列

Bandwidth(爆搜)

如何使用匹配重新排列 JavaScript 数组?

如何生成排列而不生成重复结果但具有固定数量的字符Python [重复]

通过重新排列数组来最大化数组绝对差的总和

交换某些字符后具有最大数量的给定子字符串的字符串?