Queries to count characters having odd frequency in a range [L, R]
Last Updated :
14 Jun, 2021
Given a string S of length N, consisting of lower case alphabets, and queries Q[][] of the form [L, R], the task is to count the number of characters appearing an odd number of times in the range [L, R].
Examples :
Input: S = “geeksforgeeks”, Q[][] = {{2, 4}, {0, 3}, {0, 12}}
Output: 3 2 3
Explanation:
Characters occurring odd number of times in [2, 4] : {‘e’, ‘k’, ‘s’}.
Characters occurring odd number of times in [0, 3] : {‘g’, ‘k’}.
Characters occurring odd number of times in [0, 12 ] : {‘f’, ‘o’, ‘r’}.
Input: S = “hello”, Q[][] = {{0, 4}}
Output: 3
Explanation: Characters occurring odd number of times in [0, 4] : {‘h’, ‘e’, ‘o’}.
Approach :
Follow the steps below to solve the problem:
- Each character can be represented with a unique power of two (in ascending order). For example, 20 for ‘a’, 21 for ‘b’ and so on, up to 225 for ‘z’.
- Initialize an array arr[] of size N where arr[i] is the corresponding integer value of S[i].
- Construct a prefix array prefix[] of size N where prefix[i] is the value of XOR operation performed on all the numbers from arr[0] to arr[i].
- The number of set bits in the XOR value of {arr[L], arr[L + 1], …, arr[R – 1], arr[R]} gives the required answer for the given range [L, R].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void queryResult( int prefix[],
pair< int , int > Q)
{
int l = Q.first;
int r = Q.second;
if (l == 0) {
int xorval = prefix[r];
cout << __builtin_popcount(xorval)
<< endl;
}
else {
int xorval = prefix[r]
^ prefix[l - 1];
cout << __builtin_popcount(xorval)
<< endl;
}
}
void calculateCount(string S,
pair< int , int > Q[],
int m)
{
int n = S.length();
int arr[n];
for ( int i = 0; i < n; i++) {
arr[i] = (1 << (S[i] - 'a' ));
}
int prefix[n];
int x = 0;
for ( int i = 0; i < n; i++) {
x ^= arr[i];
prefix[i] = x;
}
for ( int i = 0; i < m; i++) {
queryResult(prefix, Q[i]);
}
}
int main()
{
string S = "geeksforgeeks" ;
pair< int , int > Q[] = { { 2, 4 },
{ 0, 3 },
{ 0, 12 } };
calculateCount(S, Q, 3);
}
|
Java
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void queryResult( int prefix[], pair Q)
{
int l = Q.first;
int r = Q.second;
if (l == 0 )
{
int xorval = prefix[r];
System.out.print(Integer.bitCount(xorval) + "\n" );
}
else
{
int xorval = prefix[r] ^ prefix[l - 1 ];
System.out.print(Integer.bitCount(xorval) + "\n" );
}
}
static void calculateCount(String S, pair Q[], int m)
{
int n = S.length();
int [] arr = new int [n];
for ( int i = 0 ; i < n; i++)
{
arr[i] = ( 1 << (S.charAt(i) - 'a' ));
}
int [] prefix = new int [n];
int x = 0 ;
for ( int i = 0 ; i < n; i++)
{
x ^= arr[i];
prefix[i] = x;
}
for ( int i = 0 ; i < m; i++)
{
queryResult(prefix, Q[i]);
}
}
public static void main(String[] args)
{
String S = "geeksforgeeks" ;
pair Q[] = { new pair( 2 , 4 ),
new pair( 0 , 3 ), new pair( 0 , 12 )};
calculateCount(S, Q, 3 );
}
}
|
Python3
def queryResult(prefix, Q):
l = Q[ 0 ]
r = Q[ 1 ]
if (l = = 0 ):
xorval = prefix[r]
print ( bin (xorval).count( '1' ))
else :
xorval = prefix[r] ^ prefix[l - 1 ]
print ( bin (xorval).count( '1' ))
def calculateCount(S, Q, m):
n = len (S)
arr = [ 0 ] * n
for i in range (n):
arr[i] = ( 1 << ( ord (S[i]) - ord ( 'a' )))
prefix = [ 0 ] * n
x = 0
for i in range (n):
x ^ = arr[i]
prefix[i] = x
for i in range (m):
queryResult(prefix, Q[i])
if __name__ = = '__main__' :
S = "geeksforgeeks"
Q = [ [ 2 , 4 ],
[ 0 , 3 ],
[ 0 , 12 ] ]
calculateCount(S, Q, 3 )
|
C#
using System;
class GFG{
class pair
{
public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void queryResult( int []prefix, pair Q)
{
int l = Q.first;
int r = Q.second;
if (l == 0)
{
int xorval = prefix[r];
Console.Write(countSetBits(xorval) + "\n" );
}
else
{
int xorval = prefix[r] ^ prefix[l - 1];
Console.Write(countSetBits(xorval) + "\n" );
}
}
static void calculateCount(String S, pair []Q,
int m)
{
int n = S.Length;
int [] arr = new int [n];
for ( int i = 0; i < n; i++)
{
arr[i] = (1 << (S[i] - 'a' ));
}
int [] prefix = new int [n];
int x = 0;
for ( int i = 0; i < n; i++)
{
x ^= arr[i];
prefix[i] = x;
}
for ( int i = 0; i < m; i++)
{
queryResult(prefix, Q[i]);
}
}
static int countSetBits( long x)
{
int setBits = 0;
while (x != 0)
{
x = x & (x - 1);
setBits++;
}
return setBits;
}
public static void Main(String[] args)
{
String S = "geeksforgeeks" ;
pair []Q = { new pair(2, 4),
new pair(0, 3),
new pair(0, 12) };
calculateCount(S, Q, 3);
}
}
|
Javascript
<script>
function queryResult(prefix, Q)
{
let l = Q[0];
let r = Q[1];
if (l == 0)
{
let xorval = prefix[r];
document.write(countSetBits(xorval) + "</br>" );
}
else
{
let xorval = prefix[r] ^ prefix[l - 1];
document.write(countSetBits(xorval) + "</br>" );
}
}
function calculateCount(S, Q, m)
{
let n = S.length;
let arr = new Array(n);
for (let i = 0; i < n; i++)
{
arr[i] = (1 << (S[i].charCodeAt() - 'a' .charCodeAt()));
}
let prefix = new Array(n);
let x = 0;
for (let i = 0; i < n; i++)
{
x ^= arr[i];
prefix[i] = x;
}
for (let i = 0; i < m; i++)
{
queryResult(prefix, Q[i]);
}
}
function countSetBits(x)
{
let setBits = 0;
while (x != 0)
{
x = x & (x - 1);
setBits++;
}
return setBits;
}
let S = "geeksforgeeks" ;
let Q = [ [2, 4], [0, 3], [0, 12] ];
calculateCount(S, Q, 3);
</script>
|
Time Complexity: O(N + Q)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...