📜  允许重排的最小等回文切割

📅  最后修改于: 2021-10-28 01:34:23             🧑  作者: Mango

给定一个长度为 n 的字符串。在重新排列字符串(如果需要)后找到可能的最小切割次数,这样每个切割都是回文并且每个切割的长度相等。即,发现,可通过将所述给定的字符串,如果字符串的重排划分之前允许获得相等的长度的回文的最小数目。

例子:

Input : string = "aabaac"
Output : 2
Explanation : Rearrange the string as "abaaca"
              and cut into "aba" and "aca"

Input : string = "aabbccdd"
Output : 1
Explanation : Rearrange the string as "abcddcba"
              This is a palindrome and cannot be 
              cut further.

如果我们仔细观察,我们的问题就归结为计算具有赔率和偶数的字符。以下是可能的情况,

  1. 如果字符出现在字符串中只有甚至数那么答案将是1,因为我们可以重新把整个字符串形成回文。
  2. 如果只有一个字符为奇数,那么答案也将是 1,因为我们可以
    重新排列整个字符串以形成回文。
  3. 如果有多个字符为奇数,那么我们将创建两个单独的字符列表——一个用于奇数字符,另一个用于偶数字符。现在,如果我们注意到如果一个字符的计数为奇数,那么如果我们从中减去 1,计数将变为偶数。因此,我们将在奇数列表中仅插入一次具有奇数计数的元素。我们将插入具有偶数计数 (evenCount/2) 次的元素,即它们计数的一半在偶数列表中。现在我们的问题是将偶数元素均匀分布在奇数元素中,形成等长的回文。假设偶数个字符的列表是偶数,奇数个字符是奇数。如果even.size() 可以被odd.size() 整除,我们的答案将是odd.size() 否则我们会将元素从偶数列表转移到奇数列表,直到even.size() 可以被odd.size() 整除。

下面是上述想法的实现:

// CPP program to find minimum number of palindromic 
// cuts of equal length 
#include
using namespace std;
  
// function to find minimum number of 
// palindromic cuts of equal length 
int minPalindromeCuts(string str)
{   
    // map to store count of characters
    unordered_map m;
      
    // store count of characters in a map
    for (int i=0;i even;
      
    // list to store odd count characters
    vector odd;
      
    for (auto itr = m.begin(); itr!=m.end(); itr++)
    {  
        // add odd count characters only once and 
        // decrement count by 1
        if (itr->second%2!=0)
        {
            odd.push_back(itr->first);
            itr->second--;
        }
    }
      
    for (auto itr = m.begin(); itr!=m.end(); itr++)
    {
        if (itr->second%2==0)
        {   
            // add even count characters half of their
            // count to the even list so that we can 
            // simply repeat the even list on both 
            // sides of an odd char to generate a 
            // palindrome
            for (int i=0;i<(itr->second)/2;i++)            
                even.push_back(itr->first);
        }
    }
      
    // if there is no odd count characters or 
    // only 1 odd count character, return 1
    if (odd.size() <= 1)    
        return 1;
      
    else 
    {
        // Move some characters from even list over 
        // to odd list to make palindrome work
        while (odd.size() > 0 && even.size() > 0 &&
               even.size() % odd.size() != 0) 
        {
            odd.push_back(even.back());
            odd.push_back(even.back());
            even.pop_back();
        }
          
        return odd.size();
    }
}
  
// driver code
int main()
{
    string str = "aabaac";    
    cout << minPalindromeCuts(str);
    return 0;
}

输出:

2

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程