Open in App
Not now

# Minimum length of the sub-string whose characters can be used to form a palindrome of length K

• Last Updated : 10 May, 2022

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:
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.

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

## Javascript

 ``

Output:

`5`

My Personal Notes arrow_drop_up
Related Articles