How can we make maximum number of palindromic subs

2019-08-25 07:40发布

问题:

A string is called a substring of another string, if it can be obtained from that string by dropping some (possibly zero) number of characters from the beginning and from the end of it.

For example, abc, ab, and c are substrings of the string abc, while ac and d are not.

Let's define a palindromic count of the string as the number of its substrings that are palindromes.

For example, the palindromic count of the string aaa is 6, because all of its substrings are palindromes. And the palindromic count of the string abc is 3, because only its substrings of length 1 are palindromes.

So, two more examples:

  1. if string -> oolol

    answer = ololo,  9 substrings can be formed
    'o', 'l', 'o', 'l', 'o', 'olo', 'lol', 'olo', 'ololo'
    
  2. if string -> gagadbcgghhchbdg

    answer = abccbaghghghgdfd, 29 substrings can be formed
    

You are given a string s. You can arbitrarily rearrange its characters. You goal is to obtain a string with the maximum possible value of palindromic count.

回答1:

The best possible rearrangement of the string which yields the maximum number of palindromes could be that of a sorted string. Take, for example, the string abcabc and let n denote the size of the string in general.

We can rearrange the string to form a palindrome abc|cba, which will yield palindromic substrings of length n (all single chars) + n/2 (picking substring across reflection point) + {cases where there exists a palindrome at either of the reflection point, which in this case is 0}.

We can also rearrange the string to form palindromic pairs of the form (aa)(bb)(cc), which will yield n (single chars) + n/2 (pair-wise substring) + {other possible palindromic substrings} palindromes.

Similarly, a 3-pair palindrome can be formed as well (aba)(cbc), in which case the number of palindromes will be n + n/3 + { .. }

Clearly, as we form more m-paired palindrome, the number of palindromic substrings will fall. Hence we need to consider Case I and Case II. Of the two, it is better possible to maximize the {other ..} case for Case II by increasing the density of equal characters appearing together which is the case in a sorted string. Hence, a sorted string should yield an optimal answer.

Hence for your case oolol -> llooo will given an optimal result of 9 and gagadbcgghhchbdg -> aabbccddfgggghhh will give the optimal result of 29 as well. You can check for any string using this code: 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"))))