Count of K-size substrings having palindromic permutations

Given a string str consist 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 any permutation is palindrome are {“abb”, “bba”, “aca”}.

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

Naive Approach: A naive solution is to run two-loop to generate all substring 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 Window Sliding Technique and using frequency array of size 26. Below are the steps:



  1. Store the frequency of first K elements of the given string in frequency array(say freq[]).
  2. Using frequency array, check the count of elements having an odd frequency, if it is less than 2, then increment 
    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 frequency array having an odd frequency, if it is less than 2, then increment the count of 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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// To store the frequency array
vector<int> freq(26);
  
// Function to check palindromic of
// of any substring using frequency array
bool 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 palindromic
int countPalindromePermutation(
    string s, int k)
{
  
    // Computing the frequncy of
    // first K charcter 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 Code
int main()
{
    // Given string str
    string str = "abbaca";
  
    // Window of size K
    int K = 3;
  
    // Function Call
    cout << countPalindromePermutation(str, K)
         << endl;
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
  
class GFG{
  
// To store the frequency array
static int []freq = new int[26];
  
// Function to check palindromic of
// of any subString using frequency array
static 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 palindromic
static int countPalindromePermutation(char []s,
                                      int k)
{
  
    // Computing the frequncy of
    // first K charcter 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 Code
public 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
  
# To store the frequency array 
freq = [0] * 26
  
# Function to check palindromic of 
# of any substring using frequency array 
def 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 palindromic 
def countPalindromePermutation(s, k): 
  
    # Computing the frequncy of 
    # first K charcter 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 poof window 
    i = 0
    j =
  
    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 str 
str = "abbaca"
  
# Window of size K 
K = 3
  
# Function call 
print(countPalindromePermutation(str, K))
  
# This code is contributed by code_hunt
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
  
class GFG{
  
// To store the frequency array
static int []freq = new int[26];
  
// Function to check palindromic of
// of any subString using frequency array
static 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 palindromic
static int countPalindromePermutation(char []s,
                                      int k)
{
    int i = 0;
      
    // Computing the frequncy of
    // first K charcter 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 Code
public 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
chevron_right

Output: 
3

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





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : amit143katiyar, code_hunt

Article Tags :