最大化由给定字符串形成的 K 个回文字符串的最小长度
给定一个长度为N的字符串str和一个整数K ,任务是通过从给定字符串中选择字符来形成K个不同的字符串,使得形成的所有字符串都是回文并且K个字符串中最小的字符串的长度是最大可能的.
例子:
Input: str = “qrsprtps”, K = 2
Output: 3
Explanation: The 2 strings are: “pqp” and ” rssr”.
Using 2 ‘p’ and 1 ‘q’ the 1st string is formed and using 2 ‘r’ and 2 ‘s’ the 2nd string is formed.
The 1st string is the smallest among the K strings and is of length 3 so the answer is 3.
Input: str = “aaaabcbabca”, K = 3
Output: 3
Explanation: Possible 3 palindromic strings of maximum possible length are: “aba”, “aba”, “aba”.
The length of the smallest string among these is 3.
方法:该方法基于贪婪技术。尝试将一对相同的字符平均分配给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)