Count substrings of a given string whose anagram is a palindrome - GeeksforGeeks

02 Feb, 2022
Given a string S of length N containing only lowercase alphabets, the task is to print the count of substrings of the given string whose anagram is palindromic.
Examples:
Input: S = “aaaa”Output: 10Explanation:Possible substrings are {“a”, “a”, “a”, “a”, “aa”, “aa”, “aa”, “aaa”, “aaa”, “aaaa”}. Since all substrings are have palindromic anagrams, the required answer is 10.
Input: S = “abc”Output: 3
Naive Approach: The idea is to generate all substrings of the given string and for each substring, check whether its anagram is a palindrome or not. Keep increasing the count of substrings for which the above condition is found to be true. Finally, print the count of all such substrings. Time Complexity: O(N3)Auxiliary Space: O(N)
Bit Masking Approach: The idea is to generate the masks of 26-bit numbers as there are 26 characters. Also, observe that if the anagram of some string is a palindrome, then the frequencies of its characters except at most one character must be even. Follow the steps below to solve the problem:
Traverse the string and initialize a variable X = 0 at each index.
From every ithe index, traverse the string over a range of indices [i, N – 1], and for each character S[j], calculate Bitwise XOR of X and 2(S[j] – ‘a’), where 0th bit represents if the frequency of a is odd, 1st bit represents if the frequency of b is odd, and so on.
Then, check if X & (X – 1) is equal to 0 or not. If found to be true, then increment the count by 1.  
Illustration: Suppose, X = (0001000)2 => (X – 1) will be represented as (0000111)2. Therefore, X & (X – 1) = 0
Once the above steps are exhausted, print the count obtained.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Function to print count of substrings// whose anagrams are palindromicvoid countSubstring(string s){    // Stores the answer    int res = 0;     // Iterate over the string    for (int i = 0;         i < s.length(); i++) {         int x = 0;         for (int j = i;             j < s.length(); j++) {             // Set the current character            int temp = 1 << s[j] - 'a';             // Parity update            x ^= temp;            if ((x & (x - 1)) == 0)                res++;        }    }     // Print the final count    cout << res;} // Driver Codeint main(){    string str = "aaa";     // Function Call    countSubstring(str);     return 0;}
// Java program for// the above approachclass GFG{ // Function to print count of subStrings// whose anagrams are palindromicstatic void countSubString(String s){  // Stores the answer  int res = 0;   // Iterate over the String  for (int i = 0; i < s.length(); i++)  {    int x = 0;    for (int j = i; j < s.length(); j++)    {      // Set the current character      int temp = 1 << s.charAt(j) - 'a';       // Parity update      x ^= temp;      if ((x & (x - 1)) == 0)        res++;    }  }   // Print the final count  System.out.print(res);} // Driver Codepublic static void main(String[] args){  String str = "aaa";   // Function Call  countSubString(str);}} // This code is contributed by shikhasingrajput
# Python3 program for# the above approach # Function to print count of subStrings# whose anagrams are palindromicdef countSubString(s):       # Stores the answer    res = 0;     # Iterate over the String    for i in range(len(s)):        x = 0;        for j in range(i, len(s)):                       # Set the current character            temp = 1 << ord(s[j]) - ord('a');             # Parity update            x ^= temp;            if ((x & (x - 1)) == 0):                res += 1;     # Print final count    print(res); # Driver Codeif __name__ == '__main__':    str = "aaa";     # Function Call    countSubString(str); # This code is contributed by 29AjayKumar
// C# program for// the above approachusing System;class GFG{ // Function to print count of subStrings// whose anagrams are palindromicstatic void countSubString(String s){  // Stores the answer  int res = 0;   // Iterate over the String  for (int i = 0; i < s.Length; i++)  {    int x = 0;     for (int j = i; j < s.Length; j++)    {      // Set the current character      int temp = 1 << s[j] - 'a';       // Parity update      x ^= temp;      if ((x & (x - 1)) == 0)        res++;    }  }   // Print the readonly count  Console.Write(res);} // Driver Codepublic static void Main(String[] args){  String str = "aaa";   // Function Call  countSubString(str);}} // This code is contributed by shikhasingrajput
<script> // JavaScript  program for//the above approach // Function to print count of subStrings// whose anagrams are palindromicfunction countSubString(s){  // Stores the answer  let res = 0;    // Iterate over the String  for (let i = 0; i < s.length; i++)  {    let x = 0;    for (let j = i; j < s.length; j++)    {      // Set the current character      let temp = 1 << s[j] - 'a';        // Parity update      x ^= temp;      if ((x & (x - 1)) == 0)        res++;    }  }    // Print the final count  document.write(res);}       // Driver Code     let str = "aaa";    // Function Call  countSubString(str);     // This code is contributed by souravghosh0416.</script>
6
Time Complexity: O(N2)Auxiliary Space: O(N) 
Efficient Approach: To optimize the above Bit Masking technique, the idea is to use a Map. Follow the steps below to solve the problem: 
Initialize a map to store the frequencies of the masks. Initialize a variable X = 0.Traverse the string and for every ith index, calculate Bitwise XOR of X and 2(S[j] – ‘a’) and update the answer by adding the frequency of the current value of X in the Map because if any substring from 0 to j has the same mask as that of X, which is a mask for substring from 0 to i, then substring S[j + 1, i] will have even frequencies, where j < i.Also add the frequencies of masks X xor 2k, where, 0 ≤ k < 26. After that, increment the frequency of X by 1.Repeat the above steps for each index of the given string.After traversing the given string, print the required answer.
Initialize a map to store the frequencies of the masks. Initialize a variable X = 0.
Traverse the string and for every ith index, calculate Bitwise XOR of X and 2(S[j] – ‘a’) and update the answer by adding the frequency of the current value of X in the Map because if any substring from 0 to j has the same mask as that of X, which is a mask for substring from 0 to i, then substring S[j + 1, i] will have even frequencies, where j < i.
Also add the frequencies of masks X xor 2k, where, 0 ≤ k < 26. After that, increment the frequency of X by 1.
Repeat the above steps for each index of the given string.
After traversing the given string, print the required answer.
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Function to get the count of substrings// whose anagrams are palindromicvoid countSubstring(string s){    // Store the answer    int answer = 0;     // Map to store the freq of masks    unordered_map<int, int> m;     // Set frequency for mask    // 00...00 to 1    m[0] = 1;     // Store mask in x from 0 to i    int x = 0;    for (int j = 0; j < s.length(); j++) {        x ^= 1 << (s[j] - 'a');         // Update answer        answer += m[x];        for (int i = 0; i < 26; ++i) {            answer += m[x ^ (1 << i)];        }         // Update frequency        m[x] += 1;    }     // Print the answer    cout << answer;} // Driver Codeint main(){    string str = "abab";     // Function Call    countSubstring(str);    return 0;}
// Java program for// the above approachimport java.util.*;class GFG { // Function to get the count of subStrings// whose anagrams are palindromicstatic void countSubString(String s){  // Store the answer  int answer = 0;   // Map to store the freq of masks  HashMap<Integer,          Integer> m = new HashMap<Integer,                                   Integer>();     // Set frequency for mask  // 00...00 to 1  m.put(0, 1);   // Store mask in x from 0 to i  int x = 0;  for (int j = 0; j < s.length(); j++)  {    x ^= 1 << (s.charAt(j) - 'a');     // Update answer    answer += m.containsKey(x) ? m.get(x) : 0;    for (int i = 0; i < 26; ++i)    {      answer += m.containsKey(x ^ (1 << i)) ?                m.get(x ^ (1 << i)) : 0;    }     // Update frequency    if (m.containsKey(x))      m.put(x, m.get(x) + 1);    else      m.put(x, 1);  }   // Print the answer  System.out.print(answer);} // Driver Codepublic static void main(String[] args){  String str = "abab";   // Function Call  countSubString(str);}} // This code is contributed by shikhasingrajput
# Python3 program for the above approachfrom collections import defaultdict # Function to get the count of substrings# whose anagrams are palindromicdef countSubstring(s):     # Store the answer    answer = 0     # Map to store the freq of masks    m = defaultdict(lambda : 0)     # Set frequency for mask    # 00...00 to 1    m[0] = 1     # Store mask in x from 0 to i    x = 0         for j in range(len(s)):        x ^= 1 << (ord(s[j]) - ord('a'))         # Update answer        answer += m[x]        for i in range(26):            answer += m[x ^ (1 << i)]         # Update frequency        m[x] += 1     # Print the answer    print(answer) # Driver Codestr = "abab" # Function callcountSubstring(str) # This code is contributed by Shivam Singh
// C# program for// the above approachusing System;using System.Collections.Generic;class GFG{ // Function to get the count of// subStrings whose anagrams// are palindromicstatic void countSubString(String s){  // Store the answer  int answer = 0;   // Map to store the freq of masks  Dictionary<int,             int> m = new Dictionary<int,                                     int>();     // Set frequency for mask  // 00...00 to 1  m.Add(0, 1);   // Store mask in x from 0 to i  int x = 0;  for (int j = 0; j < s.Length; j++)  {    x ^= 1 << (s[j] - 'a');     // Update answer    answer += m.ContainsKey(x) ? m[x] : 0;    for (int i = 0; i < 26; ++i)    {      answer += m.ContainsKey(x ^ (1 << i)) ?                m[x ^ (1 << i)] : 0;    }     // Update frequency    if (m.ContainsKey(x))      m[x] = m[x] + 1;    else      m.Add(x, 1);  }   // Print the answer  Console.Write(answer);} // Driver Codepublic static void Main(String[] args){  String str = "abab";   // Function Call  countSubString(str);}} // This code is contributed by shikhasingrajput
<script> // JavaScript program for the above approach // Function to get the count of substrings// whose anagrams are palindromicfunction countSubstring(s){    // Store the answer    var answer = 0;     // Map to store the freq of masks    var m = new Map();     // Set frequency for mask    // 00...00 to 1    m.set(0, 1);     // Store mask in x from 0 to i    var x = 0;    for (var j = 0; j < s.length; j++) {        x ^= 1 << (s[j].charCodeAt(0) - 'a'.charCodeAt(0));         // Update answer        answer += m.has(x)? m.get(x):0;        for (var i = 0; i < 26; ++i) {            answer += m.has(x ^ (1 << i))?m.get(x ^ (1 << i)):0;        }         // Update frequency        if(m.has(x))            m.set(x, m.get(x)+1)        else            m.set(x, 1)    }     // Print the answer    document.write( answer);} // Driver Codevar str = "abab"; // Function CallcountSubstring(str);  </script>
7
Time Complexity: O(N)Auxiliary Space: O(N)
SHIVAMSINGH67
shikhasingrajput
29AjayKumar
souravghosh0416
rutvik_56
ankita_saini
simmytarika5
anagram
frequency-counting
palindrome
substring
Bit Magic
Hash
Mathematical
Strings
Hash
Strings
Mathematical
Bit Magic
palindrome
anagram
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Cyclic Redundancy Check and Modulo-2 Division
Little and Big Endian Mystery
Program to find whether a given number is power of 2
Binary representation of a given number
Bits manipulation (Important tactics)
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Internal Working of HashMap in Java
Hashing | Set 1 (Introduction)
Hashing | Set 3 (Open Addressing)
Count pairs with given sum