Count Substrings with even frequency of each character and one exception
Last Updated :
24 Feb, 2023
Given a string S (‘a’ ? S[i] ? ‘t’) of length N (1 ? N ? 105), which consists of lowercase English alphabets, the task is to count all substrings such that the frequency of all characters should be even or all characters should occur an even number of times except any one character which might occur an odd number of times.
Examples:
Input: S = “aab”
Output: 5
Explanation: The five valid substrings are underlined below:
“aab” -> “a”
“aab” -> “a”
“aab” -> “aa”
“aab” -> “b”
“aab” -> “aab”
Input: S = “abba”
Output: 8
The idea is to use Bitmasking technique, We’ll encode all visited character from 0 to ith index into our mask and add count of same mask that had occurred previously.
Follow the steps to implement the above idea:
- Create an array dp[] of size 2m where m is the distinct character in the given string [because there is this much possibility for any character to occur till any index]. dp[i] will Store the count of valid substrings having mask i
- Initialize dp[0] = 1, as there is one possible way of the valid substring having mask 0 (i.e, if we don’t consider any character from the string).
- Iterate from i = 0 to N-1:
- Calculate the current mask at (S[i] – ‘a’) index.
- Add all the previous valid substrings that had the same mask
- Iterate from j = 0 to 20 for the current mask:
- Flip the jth bit of the current mask.
- Add all previous valid substrings having the same mask
- Increment the frequency of the current mask
- Return the result
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > dp;
long long allvalidString(string& word)
{
dp.resize(1 << 20);
long long mask = 0, result = 0;
dp[0] = 1;
for ( auto ch : word) {
mask ^= 1 << (ch - 'a' );
result += dp[mask];
for ( int i = 0; i < 20; i++) {
result += dp[mask ^ (1 << i)];
}
dp[mask]++;
}
return result;
}
int main()
{
string s = "abba" ;
cout << allvalidString(s);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int dp[] = new int [ 1 << 20 ];
public static long allvalidString(String word)
{
int mask = 0 , result = 0 ;
dp[ 0 ] = 1 ;
for ( int j = 0 ; j < word.length(); j++) {
char ch = word.charAt(j);
mask ^= 1 << (ch - 'a' );
result += dp[mask];
for ( int i = 0 ; i < 20 ; i++) {
result += dp[mask ^ ( 1 << i)];
}
dp[mask]++;
}
return result;
}
public static void main(String[] args)
{
String s = "abba" ;
System.out.print(allvalidString(s));
}
}
|
Python3
dp = []
def allvalidString(word):
global dp
dp = [ 0 for _ in range ( 1 << 20 )]
mask = 0
result = 0
dp[ 0 ] = 1
for ch in word:
mask ^ = 1 << ( ord (ch) - ord ( 'a' ))
result + = dp[mask]
for i in range ( 0 , 20 ):
result + = dp[mask ^ ( 1 << i)]
dp[mask] + = 1
return result
if __name__ = = "__main__" :
s = "abba"
print (allvalidString(s))
|
C#
using System;
using System.Collections;
public class GFG {
public static int allvalidString( string s)
{
int [] dp = new int [1 << 20];
int mask = 0;
int result = 0;
dp[0] = 1;
for ( int i = 0; i < s.Length; i++) {
mask ^= 1 << (s[i] - 'a' );
result += dp[mask];
for ( int j = 0; j < 20; j++) {
result += dp[mask ^ (1 << j)];
}
dp[mask]++;
}
return result;
}
public static void Main( string [] args)
{
string s = "abba" ;
Console.WriteLine(allvalidString(s));
}
}
|
Javascript
let dp = new Array(1 << 20).fill(0);
function allvalidString(word) {
let mask = 0, result = 0;
dp[0] = 1;
for (let ch of word) {
mask ^= 1 << (ch.charCodeAt(0) - 'a' .charCodeAt(0));
result += dp[mask];
for (let i = 0; i < 20; i++) {
result += dp[mask ^ (1 << i)];
}
dp[mask]++;
}
return result;
}
let s = "abba" ;
console.log(allvalidString(s));
|
Time Complexity: O(N), where n is the length of the given string
Auxiliary Space: O(2m), where m is the distinct character in the given string.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...