其字符可用于形成长度为 K 的回文的子串的最小长度
给定一个由小写英文字母和整数K组成的字符串str 。任务是找到子串的最小长度,其字符可用于形成长度为K的回文。如果不存在这样的子字符串,则打印-1 。
例子:
Input: str = “abcda”, k = 2
Output: 5
In order to form a palindrome of length 2, both the occurrences of ‘a’ are required.
Hence, the length of the required sub-string will be 5.
Input: str = “abcde”, k = 5
Output: -1
No palindromic string of length 5 can be formed from the characters of the given string.
方法:这个想法是使用二分搜索。形成长度为K的回文所需的最小字符是K 。因此,我们的搜索域减少到[K, length(str)] 。在这个范围内应用二分查找并找到一个长度为X (K ≤ X ≤ length(S)) 的子串,使得使用这个子串的部分或全部字符可以形成一个大小为K的回文字符串。满足给定条件的最小X将是所需答案。如果不可能有这样的子字符串,则打印-1 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function that returns true if
// a palindrome can be formed using
// exactly k characters
bool isPalindrome(int freq[], int k)
{
// Variable to check if characters
// with odd frequency are present
int flag = 0;
// Variable to store maximum length
// of the palindrome that can be formed
int length = 0;
for (int i = 0; i < 26; i++) {
if (freq[i] == 0)
continue;
else if (freq[i] == 1)
flag = 1;
else {
if (freq[i] & 1)
flag = 1;
length += freq[i] / 2;
}
}
// If k is odd
if (k & 1) {
if (2 * length + flag >= k)
return true;
}
// If k is even
else {
if (2 * length >= k)
return true;
}
// If palindrome of length
// k cant be formed
return false;
}
// Function that returns true if a palindrome
// of length k can be formed from a
// sub-string of length m
bool check(string str, int m, int k)
{
// Stores frequency of characters
// of a substring of length m
int freq[26] = { 0 };
for (int i = 0; i < m; i++)
freq[str[i] - 'a']++;
// If a palindrome can be
// formed from a substring of
// length m
if (isPalindrome(freq, k))
return true;
// Check for all the substrings of
// length m, if a palindrome of
// length k can be formed
for (int i = m; i < str.length(); i++) {
freq[str[i - m] - 'a']--;
freq[str[i] - 'a']++;
if (isPalindrome(freq, k))
return true;
}
// If no palindrome of length
// k can be formed
return false;
}
// Function to return the minimum length
// of the sub-string whose characters can be
// used to form a palindrome of length k
int find(string str, int n, int k)
{
int l = k;
int h = n;
// To store the minimum length of the
// sub-string that can be used to form
// a palindrome of length k
int ans = -1;
while (l <= h) {
int m = (l + h) / 2;
if (check(str, m, k)) {
ans = m;
h = m - 1;
}
else
l = m + 1;
}
return ans;
}
// Driver code
int main()
{
string str = "abcda";
int n = str.length();
int k = 2;
cout << find(str, n, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function that returns true if
// a palindrome can be formed using
// exactly k characters
static boolean isPalindrome(int freq[], int k)
{
// Variable to check if characters
// with odd frequency are present
int flag = 0;
// Variable to store maximum length
// of the palindrome that can be formed
int length = 0;
for (int i = 0; i < 26; i++)
{
if (freq[i] == 0)
continue;
else if (freq[i] == 1)
flag = 1;
else
{
if (freq[i] % 2 == 1)
flag = 1;
length += freq[i] / 2;
}
}
// If k is odd
if (k % 2 == 1)
{
if (2 * length + flag >= k)
return true;
}
// If k is even
else
{
if (2 * length >= k)
return true;
}
// If palindrome of length
// k cant be formed
return false;
}
// Function that returns true if a palindrome
// of length k can be formed from a
// sub-string of length m
static boolean check(String str, int m, int k)
{
// Stores frequency of characters
// of a substring of length m
int []freq = new int[26];
for (int i = 0; i < m; i++)
freq[str.charAt(i) - 'a']++;
// If a palindrome can be
// formed from a substring of
// length m
if (isPalindrome(freq, k))
return true;
// Check for all the substrings of
// length m, if a palindrome of
// length k can be formed
for (int i = m; i < str.length(); i++)
{
freq[str.charAt(i-m) - 'a']--;
freq[str.charAt(i) - 'a']++;
if (isPalindrome(freq, k))
return true;
}
// If no palindrome of length
// k can be formed
return false;
}
// Function to return the minimum length
// of the sub-string whose characters can be
// used to form a palindrome of length k
static int find(String str, int n, int k)
{
int l = k;
int h = n;
// To store the minimum length of the
// sub-string that can be used to form
// a palindrome of length k
int ans = -1;
while (l <= h)
{
int m = (l + h) / 2;
if (check(str, m, k))
{
ans = m;
h = m - 1;
}
else
l = m + 1;
}
return ans;
}
// Driver code
public static void main(String[] args)
{
String str = "abcda";
int n = str.length();
int k = 2;
System.out.println(find(str, n, k));
}
}
// This code is contributed by Rajput-Ji
Python3
# Python 3 implementation of the approach
# Function that returns true if
# a palindrome can be formed using
# exactly k characters
def isPalindrome(freq, k):
# Variable to check if characters
# with odd frequency are present
flag = 0
# Variable to store maximum length
# of the palindrome that can be formed
length = 0
for i in range(26):
if (freq[i] == 0):
continue
elif (freq[i] == 1):
flag = 1
else:
if (freq[i] & 1):
flag = 1
length += freq[i] // 2
# If k is odd
if (k & 1):
if (2 * length + flag >= k):
return True
# If k is even
else:
if (2 * length >= k):
return True
# If palindrome of length
# k cant be formed
return False
# Function that returns true if a palindrome
# of length k can be formed from a
# sub-string of length m
def check(str, m, k):
# Stores frequency of characters
# of a substring of length m
freq = [0 for i in range(26)]
for i in range(m):
freq[ord(str[i]) - ord('a')] += 1
# If a palindrome can be
# formed from a substring of
# length m
if (isPalindrome(freq, k)):
return True
# Check for all the substrings of
# length m, if a palindrome of
# length k can be formed
for i in range(m, len(str), 1):
freq[ord(str[i - m]) - ord('a')] -= 1
freq[ord(str[i]) - ord('a')] += 1
if (isPalindrome(freq, k)):
return True
# If no palindrome of length
# k can be formed
return False
# Function to return the minimum length
# of the sub-string whose characters can be
# used to form a palindrome of length k
def find(str, n, k):
l = k
h = n
# To store the minimum length of the
# sub-string that can be used to form
# a palindrome of length k
ans = -1
while (l <= h):
m = (l + h) // 2
if (check(str, m, k)):
ans = m
h = m - 1
else:
l = m + 1
return ans
# Driver code
if __name__ == '__main__':
str = "abcda"
n = len(str)
k = 2
print(find(str, n, k))
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the approach
using System;
class GFG
{
// Function that returns true if
// a palindrome can be formed using
// exactly k characters
static Boolean isPalindrome(int []freq, int k)
{
// Variable to check if characters
// with odd frequency are present
int flag = 0;
// Variable to store maximum length
// of the palindrome that can be formed
int length = 0;
for (int i = 0; i < 26; i++)
{
if (freq[i] == 0)
continue;
else if (freq[i] == 1)
flag = 1;
else
{
if (freq[i] % 2 == 1)
flag = 1;
length += freq[i] / 2;
}
}
// If k is odd
if (k % 2 == 1)
{
if (2 * length + flag >= k)
return true;
}
// If k is even
else
{
if (2 * length >= k)
return true;
}
// If palindrome of length
// k cant be formed
return false;
}
// Function that returns true if a palindrome
// of length k can be formed from a
// sub-string of length m
static Boolean check(String str, int m, int k)
{
// Stores frequency of characters
// of a substring of length m
int []freq = new int[26];
for (int i = 0; i < m; i++)
freq[str[i] - 'a']++;
// If a palindrome can be
// formed from a substring of
// length m
if (isPalindrome(freq, k))
return true;
// Check for all the substrings of
// length m, if a palindrome of
// length k can be formed
for (int i = m; i < str.Length; i++)
{
freq[str[i - m] - 'a']--;
freq[str[i] - 'a']++;
if (isPalindrome(freq, k))
return true;
}
// If no palindrome of length
// k can be formed
return false;
}
// Function to return the minimum length
// of the sub-string whose characters can be
// used to form a palindrome of length k
static int find(String str, int n, int k)
{
int l = k;
int h = n;
// To store the minimum length of the
// sub-string that can be used to form
// a palindrome of length k
int ans = -1;
while (l <= h)
{
int m = (l + h) / 2;
if (check(str, m, k))
{
ans = m;
h = m - 1;
}
else
l = m + 1;
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
String str = "abcda";
int n = str.Length;
int k = 2;
Console.WriteLine(find(str, n, k));
}
}
// This code is contributed by PrinciRaj1992
PHP
= $k)
return true;
}
// If k is even
else
{
if (2 * $length >= $k)
return true;
}
// If palindrome of length
// k cant be formed
return false;
}
// Function that returns true if a palindrome
// of length k can be formed from a
// sub-string of length m
function check($str, $m, $k)
{
// Stores frequency of characters
// of a substring of length m
$freq = array_fill(0, 26, 0);
for ($i = 0; $i < $m; $i++)
$freq[ord($str[$i]) - ord('a')]++;
// If a palindrome can be
// formed from a substring of
// length m
if (isPalindrome($freq, $k))
return true;
// Check for all the substrings of
// length m, if a palindrome of
// length k can be formed
for ($i = $m; $i < strlen($str); $i++)
{
$freq[ord($str[$i - $m]) - ord('a')] -= 1;
$freq[ord($str[$i]) - ord('a')] += 1;
if (isPalindrome($freq, $k))
return true;
}
// If no palindrome of length
// k can be formed
return false;
}
// Function to return the minimum length
// of the sub-string whose characters can be
// used to form a palindrome of length k
function find($str, $n, $k)
{
$l = $k;
$h = $n;
// To store the minimum length of the
// sub-string that can be used to form
// a palindrome of length k
$ans = -1;
while ($l <= $h)
{
$m = floor(($l + $h) / 2);
if (check($str, $m, $k))
{
$ans = $m;
$h = $m - 1;
}
else
$l = $m + 1;
}
return $ans;
}
// Driver code
$str = "abcda";
$n = strlen($str);
$k = 2;
echo find($str, $n, $k);
// This code is improved by Ryuga
?>
Javascript
输出:
5