Count of K-size substrings having palindromic permutations
Last Updated :
08 Nov, 2023
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: 3
Explanation:
The substrings of size 3 whose permutation is palindrome are {"abb", "bba", "aca"}.
Input: str = "aaaa", K = 1
Output: 4
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)
Count of K-size substrings having palindromic permutations using Sliding Window Technique:
The idea is to use the Window Sliding Technique and using a frequency array of size 26.
Step-by-step approach:
- Store the frequency of the first K elements of the given string in a frequency array(say freq[]).
- 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.
- Now, linearly slide the window ahead till it reaches the end.
- 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.
- 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 <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 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 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;
}
Java
// 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 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 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
Python3
# 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 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 str
str = "abbaca"
# Window of size K
K = 3
# Function call
print(countPalindromePermutation(str, K))
# This code is contributed by code_hunt
C#
// 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 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 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
JavaScript
<script>
// Javascript program for the above approach
// To store the frequency array
var freq = Array(26).fill(0);
// Function to check palindromic of
// of any substring using frequency array
function checkPalindrome()
{
// Initialise the odd count
var oddCnt = 0;
// Traversing frequency array to
// compute the count of characters
// having odd frequency
freq.forEach(x => {
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
function countPalindromePermutation( s, k)
{
// Computing the frequency of
// first K character of the string
for (var i = 0; i < k; i++) {
freq[s[i].charCodeAt(0) - 97]++;
}
// To store the count of
// palindromic permutations
var ans = 0;
// Checking for the current window
// if it has any palindromic
// permutation
if (checkPalindrome()) {
ans++;
}
// Start and end point of window
var i = 0, j = k;
while (j < s.length) {
// Sliding window by 1
// Decrementing count of first
// element of the window
freq[s[i++].charCodeAt(0) - 97]--;
// Incrementing count of next
// element of the window
freq[s[j++].charCodeAt(0) - 97]++;
// Checking current window
// character frequency count
if (checkPalindrome()) {
ans++;
}
}
// Return the final count
return ans;
}
// Driver Code
// Given string str
var str = "abbaca";
// Window of size K
var K = 3;
// Function Call
document.write( countPalindromePermutation(str, K));
</script>
Time Complexity: O(N)
Auxiliary Space: O(1)
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Dijkstra's Algorithm to find Shortest Paths from a Source to all Given a weighted undirected graph represented as an edge list and a source vertex src, find the shortest path distances from the source vertex to all other vertices in the graph. The graph contains V vertices, numbered from 0 to V - 1.Note: The given graph does not contain any negative edge. Example
12 min read
Selection Sort Selection Sort is a comparison-based sorting algorithm. It sorts an array by repeatedly selecting the smallest (or largest) element from the unsorted portion and swapping it with the first unsorted element. This process continues until the entire array is sorted.First we find the smallest element an
8 min read