📌  相关文章
📜  最大化由给定字符串形成的 K 个回文字符串的最小长度

📅  最后修改于: 2022-05-13 01:56:06.977000             🧑  作者: Mango

最大化由给定字符串形成的 K 个回文字符串的最小长度

给定一个长度为N的字符串str和一个整数K ,任务是通过从给定字符串中选择字符来形成K个不同的字符串,使得形成的所有字符串都是回文并且K个字符串中最小的字符串的长度是最大可能的.

例子:

方法:该方法基于贪婪技术尝试将一对相同的字符平均分配给K个字符串。制作成对的相同字符以确保形成的字符串是回文。长度为N的偶数长度回文将有N/2 个这样的对,而奇数长度的回文将有一个额外的字符以及N/2对。

  • 计算给定字符串中字符的频率以及可以用这些字符组成的对数。
  • 只要有K对可用,就将这些对分布K个字符串中。 (即,如果有 5 个这样的对并且 K = 2,则将 2 对分配给每个,这样就可以形成一个 4 长度的回文字符串,单对将不分配)
  • 现在将有所有偶数长度的回文字符串。由于剩下的对不能分布在所有字符串中,因此最小字符串的长度将是分配给每个字符串的字符对数的两倍。
  • 尝试再添加 1 个字符,看看是否可以形成奇数长度的字符串。
    • 从剩余的字符中,即不是对的一部分的字符和剩余的字符对中的字符,将每个字符串添加 1 个字符以将最大长度增加 1。
    • 如果存在至少 K个这样的字符,那么对于所有字符串,只有最小长度可以增加一

下面是上述方法的实现。

C++
// C++ code to implement the approach
 
#include 
using namespace std;
 
// Function to find the maximum possible
// minimum length among the
// K palindromic strings formed
// from given string str
int form_K_Strings(string& str, int k)
{
    int n = str.size();
    unordered_map freq;
 
    // Storing the frequency of the characters
    for (auto i : str)
        freq[i]++;
 
    // Traversing the map to count
    // the number of pairs
    // that can be formed
    // and count the remaining
    // individual characters
    int pairs = 0, remChar = 0;
    for (auto i : freq) {
        pairs += (i.second / 2);
        if (i.second % 2 == 1)
            remChar++;
    }
 
    // Calculating the number of pairs
    // each string will receive
    // upon equally distributing.
    int distributed = pairs / k;
 
    // Length of these strings will be
    // twice of the pairs received.
    // This is length of the smallest string
    int res = distributed * 2;
 
    // If some pairs are left then
    // characters of the pairs can be treated
    // as individual remaining characters and
    // each pair will give 2 such characters
    int remPairs = pairs % k;
    remChar += 2 * remPairs;
 
    // If atleast k remaining characters
    // then we can add 1 character to
    // each of the strings to form
    // an odd length palindrome.
    // So now the length of the smallest
    // string will increase by 1.
    if (remChar >= k)
        res++;
 
    return res;
}
 
// Driver code
int main()
{
    string str = "qrsprtps";
    int K = 2;
 
    // Function call
    cout << form_K_Strings(str, K);
    return 0;
}


Java
// JAVA code to implement the approach
import java.util.*;
class GFG
{
 
  // Function to find the maximum possible
  // minimum length among the
  // K palindromic strings formed
  // from given string str
  public static int form_K_Strings(String str, int k)
  {
    int n = str.length();
    HashMap freq = new HashMap<>();
 
    // Stroring the frequency of the characters
    char[] strArray = str.toCharArray();
 
    for (char c : strArray) {
      if (freq.containsKey(c)) {
        freq.put(c, freq.get(c) + 1);
      }
      else {
        freq.put(c, 1);
      }
    }
 
    // Traversing the map to count
    // the number of pairs
    // that can be formed
    // and count the remaining
    // individual characters
    int pairs = 0, remChar = 0;
    for (Map.Entry i :
         freq.entrySet()) {
      pairs += (i.getValue() / 2);
      if (i.getValue() % 2 == 1)
        remChar++;
    }
 
    // Calculating the number of pairs
    // each string will receive
    // upon equally distributing.
    int distributed = pairs / k;
 
    // Length of these strings will be
    // twice of the pairs received.
    // This is length of the smallest string
    int res = distributed * 2;
 
    // If some pairs are left then
    // characters of the pairs can be treated
    // as individual remaining characters and
    // each pair will give 2 such characters
    int remPairs = pairs % k;
    remChar += 2 * remPairs;
 
    // If atleast k remaining characters
    // then we can add 1 character to
    // each of the strings to form
    // an odd length palindrome.
    // So now the length of the smallest
    // string will increase by 1.
    if (remChar >= k)
      res++;
 
    return res;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    String str = "qrsprtps";
    int K = 2;
 
    // Function call
    System.out.print(form_K_Strings(str, K));
  }
}
 
// This code is contributed by Taranpreet


Python3
# Pyython 3 code to implement the approach
from collections import defaultdict
 
# Function to find the maximum possible
# minimum length among the
# K palindromic strings formed
# from given string str
def form_K_Strings(st, k):
    n = len(st)
    freq = defaultdict(int)
 
    # Storing the frequency of the characters
    for i in st:
        freq[i] += 1
 
    # Traversing the map to count
    # the number of pairs
    # that can be formed
    # and count the remaining
    # individual characters
    pairs = 0
    remChar = 0
    for i in freq:
        pairs += (freq[i] // 2)
        if (freq[i] % 2 == 1):
            remChar += 1
 
    # Calculating the number of pairs
    # each string will receive
    # upon equally distributing.
    distributed = pairs // k
 
    # Length of these strings will be
    # twice of the pairs received.
    # This is length of the smallest string
    res = distributed * 2
 
    # If some pairs are left then
    # characters of the pairs can be treated
    # as individual remaining characters and
    # each pair will give 2 such characters
    remPairs = pairs % k
    remChar += 2 * remPairs
 
    # If atleast k remaining characters
    # then we can add 1 character to
    # each of the strings to form
    # an odd length palindrome.
    # So now the length of the smallest
    # string will increase by 1.
    if (remChar >= k):
        res += 1
 
    return res
 
# Driver code
if __name__ == "__main__":
 
    st = "qrsprtps"
    K = 2
 
    # Function call
    print(form_K_Strings(st, K))
 
    # This code is contributed by ukasp.


C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Function to find the maximum possible
  // minimum length among the
  // K palindromic strings formed
  // from given string str
  static int form_K_Strings(string str, int k)
  {
    int n = str.Length;
    Dictionary freq = 
      new Dictionary();
 
    // Stroring the frequency of the characters
    char[] strArray = str.ToCharArray();
 
    foreach (char c in strArray) {
      if (!freq.ContainsKey(c)) {
        freq.Add(c, 1);
      }
      else {
        freq += 1;
      }
    }
 
    // Traversing the map to count
    // the number of pairs
    // that can be formed
    // and count the remaining
    // individual characters
    int pairs = 0, remChar = 0;
    foreach(KeyValuePair i in freq)
    {
      pairs += (i.Value / 2);
      if (i.Value % 2 == 1)
        remChar++;
    }
 
    // Calculating the number of pairs
    // each string will receive
    // upon equally distributing.
    int distributed = pairs / k;
 
    // Length of these strings will be
    // twice of the pairs received.
    // This is length of the smallest string
    int res = distributed * 2;
 
    // If some pairs are left then
    // characters of the pairs can be treated
    // as individual remaining characters and
    // each pair will give 2 such characters
    int remPairs = pairs % k;
    remChar += 2 * remPairs;
 
    // If atleast k remaining characters
    // then we can add 1 character to
    // each of the strings to form
    // an odd length palindrome.
    // So now the length of the smallest
    // string will increase by 1.
    if (remChar >= k)
      res++;
 
    return res;
  }
 
  // Driver code
  public static void Main()
  {
    string str = "qrsprtps";
    int K = 2;
 
    // Function call
    Console.Write(form_K_Strings(str, K));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出
3

时间复杂度: O(N)
辅助空间: O(N)