Count of K-size substrings having palindromic permutations

• Last Updated : 03 Dec, 2021

Given string str consists of only lowercase alphabets and an integer K, the task is to count the number of substrings of size K such that any permutation of the substring is a palindrome.

Examples:

Input: str = “abbaca”, K = 3
Output:
Explanation:
The substrings of size 3 whose permutation is palindrome are {“abb”, “bba”, “aca”}.

Input: str = “aaaa”, K = 1
Output:
Explanation:
The substrings of size 1 whose permutation is palindrome are {‘a’, ‘a’, ‘a’, ‘a’}.

Naive Approach: A naive solution is to run a two-loop to generate all substrings of size K. For each substring formed, find the frequency of each character of the substring. If at most one character has an odd frequency, then one of its permutations will be a palindrome. Increment the count for the current substring and print the final count after all the operations.

Time Complexity: O(N*K)

Efficient Approach: This problem can be solved efficiently by using the Window Sliding Technique and using a frequency array of size 26. Below are the steps:

1. Store the frequency of the first K elements of the given string in a frequency array(say freq[]).
2. Using a frequency array, check the count of elements having an odd frequency. If it is less than 2, then the increment of the count of palindromic permutation.
3. Now, linearly slide the window ahead till it reaches the end.
4. At each iteration, decrease the count of the first element of the window by 1 and increase the count of the next element of the window by 1 and again check the count of elements in a frequency array having an odd frequency. If it is less than 2, then increase the count of the palindromic permutation.
5. Repeat the above step till we reach the end of the string and print the count of palindromic permutation.

Below is the implementation of the above approach:

C++

 // C++ program for the above approach#include using namespace std; // To store the frequency arrayvector freq(26); // Function to check palindromic of// of any substring using frequency arraybool checkPalindrome(){     // Initialise the odd count    int oddCnt = 0;     // Traversing frequency array to    // compute the count of characters    // having odd frequency    for (auto x : freq) {         if (x % 2 == 1)            oddCnt++;    }     // Returns true if odd count is atmost 1    return oddCnt <= 1;} // Function to count the total number// substring whose any permutations// are palindromicint countPalindromePermutation(    string s, int k){     // Computing the frequency of    // first K character of the string    for (int i = 0; i < k; i++) {        freq[s[i] - 97]++;    }     // To store the count of    // palindromic permutations    int ans = 0;     // Checking for the current window    // if it has any palindromic    // permutation    if (checkPalindrome()) {        ans++;    }     // Start and end point of window    int i = 0, j = k;     while (j < s.size()) {         // Sliding window by 1         // Decrementing count of first        // element of the window        freq[s[i++] - 97]--;         // Incrementing count of next        // element of the window        freq[s[j++] - 97]++;         // Checking current window        // character frequency count        if (checkPalindrome()) {            ans++;        }    }     // Return the final count    return ans;} // Driver Codeint main(){    // Given string str    string str = "abbaca";     // Window of size K    int K = 3;     // Function Call    cout << countPalindromePermutation(str, K)         << endl;    return 0;}

Java

 // Java program for the above approachimport java.util.*; class GFG{ // To store the frequency arraystatic int []freq = new int; // Function to check palindromic of// of any subString using frequency arraystatic boolean checkPalindrome(){         // Initialise the odd count    int oddCnt = 0;     // Traversing frequency array to    // compute the count of characters    // having odd frequency    for(int x : freq)    {       if (x % 2 == 1)           oddCnt++;    }     // Returns true if odd count    // is atmost 1    return oddCnt <= 1;} // Function to count the total number// subString whose any permutations// are palindromicstatic int countPalindromePermutation(char []s,                                      int k){     // Computing the frequency of    // first K character of the String    for(int i = 0; i < k; i++)    {       freq[s[i] - 97]++;    }     // To store the count of    // palindromic permutations    int ans = 0;     // Checking for the current window    // if it has any palindromic    // permutation    if (checkPalindrome())    {        ans++;    }     // Start and end point of window    int i = 0, j = k;     while (j < s.length)    {         // Sliding window by 1         // Decrementing count of first        // element of the window        freq[s[i++] - 97]--;         // Incrementing count of next        // element of the window        freq[s[j++] - 97]++;         // Checking current window        // character frequency count        if (checkPalindrome())        {            ans++;        }    }     // Return the final count    return ans;} // Driver Codepublic static void main(String[] args){         // Given String str    String str = "abbaca";     // Window of size K    int K = 3;     // Function Call    System.out.print(countPalindromePermutation(                     str.toCharArray(), K) + "\n");}} // This code is contributed by Amit Katiyar

Python3

 # Python3 program for the above approach # To store the frequency arrayfreq =  * 26 # Function to check palindromic of# of any substring using frequency arraydef checkPalindrome():     # Initialise the odd count    oddCnt = 0     # Traversing frequency array to    # compute the count of characters    # having odd frequency    for x in freq:        if (x % 2 == 1):            oddCnt += 1         # Returns true if odd count is atmost 1    return oddCnt <= 1 # Function to count the total number# substring whose any permutations# are palindromicdef countPalindromePermutation(s, k):     # Computing the frequency of    # first K character of the string    for i in range(k):        freq[ord(s[i]) - 97] += 1         # To store the count of    # palindromic permutations    ans = 0     # Checking for the current window    # if it has any palindromic    # permutation    if (checkPalindrome()):        ans += 1         # Start and end point of window    i = 0    j = k     while (j < len(s)):         # Sliding window by 1         # Decrementing count of first        # element of the window        freq[ord(s[i]) - 97] -= 1        i += 1         # Incrementing count of next        # element of the window        freq[ord(s[j]) - 97] += 1        j += 1         # Checking current window        # character frequency count        if (checkPalindrome()):            ans += 1                 # Return the final count    return ans # Driver Code # Given string strstr = "abbaca" # Window of size KK = 3 # Function callprint(countPalindromePermutation(str, K)) # This code is contributed by code_hunt

C#

 // C# program for the above approachusing System; class GFG{ // To store the frequency arraystatic int []freq = new int; // Function to check palindromic of// of any subString using frequency arraystatic bool checkPalindrome(){         // Initialise the odd count    int oddCnt = 0;     // Traversing frequency array to    // compute the count of characters    // having odd frequency    foreach(int x in freq)    {        if (x % 2 == 1)            oddCnt++;    }     // Returns true if odd count    // is atmost 1    return oddCnt <= 1;} // Function to count the total number// subString whose any permutations// are palindromicstatic int countPalindromePermutation(char []s,                                      int k){    int i = 0;         // Computing the frequency of    // first K character of the String    for(i = 0; i < k; i++)    {       freq[s[i] - 97]++;    }     // To store the count of    // palindromic permutations    int ans = 0;     // Checking for the current window    // if it has any palindromic    // permutation    if (checkPalindrome())    {        ans++;    }     // Start and end point of window    int j = k;        i = 0;     while (j < s.Length)    {                 // Sliding window by 1         // Decrementing count of first        // element of the window        freq[s[i++] - 97]--;         // Incrementing count of next        // element of the window        freq[s[j++] - 97]++;         // Checking current window        // character frequency count        if (checkPalindrome())        {            ans++;        }    }         // Return the final count    return ans;} // Driver Codepublic static void Main(String[] args){         // Given String str    String str = "abbaca";     // Window of size K    int K = 3;     // Function Call    Console.Write(countPalindromePermutation(                  str.ToCharArray(), K) + "\n");}} // This code is contributed by Amit Katiyar

Javascript


Output:
3

Time Complexity: O(N)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up