Related Articles
Minimum length of the sub-string whose characters can be used to form a palindrome of length K
• Last Updated : 01 Aug, 2019

Given a string str consisting of lowercase English letters and an integer K. The task is to find the minimum length of the sub-string whose characters can be used to form a palindrome of length K. If no such sub-string exists then print -1.

Examples:

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.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: The idea is to use Binary Search. Minimum character needed to form a palindrome of length K is K. So, our search domain gets reduced to [K, length(str)]. Apply binary search in this range and find a sub-string of length X (K ≤ X ≤ length(S)) such that using some or all characters of this sub-string a palindromic string of size K can be formed. Minimum X which satisfies the given condition will be the required answer. If no such such sub-string is possible then print -1.

Below is the implementation of the above approach:

## 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 ` `?> `

Output:

```5
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :