Given a string S of size N and Q queries. Every query consists of L and R ( 0 < = L < = R < N ) . The task is to print the character that occurs the maximum number of times in the given range. If there are multiple characters that occur maximum number of times then print the lexicographically smallest of them.
Note: S consists of lowercase English letters.
Examples:
Input:
str = “geekss”,
Q = 2
0 2
3 5
Output:
e
s
Input:
str = “striver”,
Q = 3
0 1
1 6
5 6
Output:
s
r
e
Naive Approach: A naive approach is to iterate from L to R for every query and find the character that appears the maximum number of times using frequency array of size 26.
Time Complexity: O(max(R-L, 26)) per query, as we will be using a loop to traverse R-L times.
Auxiliary Space: O(26), as we will be using extra space for frequency array.
Efficient Approach: An efficient approach is to use a prefix sum array to efficiently answer the query. Let pre[i][j] stores the occurrence of a character j till the i-th index. For every query occurrence of a character j will be pre[r][j] – pre[l-1][j](if l > 0). Find the lexicographically smallest character that appears the maximum number of times by iterating the 26 lowercase letters.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void solveQueries(string str, vector<vector< int > >& query)
{
int len = str.size();
int Q = query.size();
int pre[len][26];
memset (pre, 0, sizeof pre);
for ( int i = 0; i < len; i++) {
pre[i][str[i] - 'a' ]++;
if (i) {
for ( int j = 0; j < 26; j++)
pre[i][j] += pre[i - 1][j];
}
}
for ( int i = 0; i < Q; i++) {
int l = query[i][0];
int r = query[i][1];
int maxi = 0;
char c = 'a' ;
for ( int j = 0; j < 26; j++) {
int times = pre[r][j];
if (l)
times -= pre[l - 1][j];
if (times > maxi) {
maxi = times;
c = char ( 'a' + j);
}
}
cout << "Query " << i + 1 << ": " << c << endl;
}
}
int main()
{
string str = "striver" ;
vector<vector< int > > query;
query.push_back({ 0, 1 });
query.push_back({ 1, 6 });
query.push_back({ 5, 6 });
solveQueries(str, query);
}
|
Java
class GFG
{
static void solveQueries(String str,
int [][] query)
{
int len = str.length();
int Q = query.length;
int [][] pre = new int [len][ 26 ];
for ( int i = 0 ; i < len; i++)
{
pre[i][str.charAt(i) - 'a' ]++;
if (i > 0 )
{
for ( int j = 0 ; j < 26 ; j++)
pre[i][j] += pre[i - 1 ][j];
}
}
for ( int i = 0 ; i < Q; i++)
{
int l = query[i][ 0 ];
int r = query[i][ 1 ];
int maxi = 0 ;
char c = 'a' ;
for ( int j = 0 ; j < 26 ; j++)
{
int times = pre[r][j];
if (l > 0 )
times -= pre[l - 1 ][j];
if (times > maxi)
{
maxi = times;
c = ( char )( 'a' + j);
}
}
System.out.println( "Query" + (i + 1 ) + ": " + c);
}
}
public static void main(String[] args)
{
String str = "striver" ;
int [][] query = {{ 0 , 1 }, { 1 , 6 }, { 5 , 6 }};
solveQueries(str, query);
}
}
|
Python3
def solveQueries( Str , query):
ll = len ( Str )
Q = len (query)
pre = [[ 0 for i in range ( 256 )]
for i in range (ll)]
for i in range (ll):
pre[i][ ord ( Str [i])] + = 1
if (i):
for j in range ( 256 ):
pre[i][j] + = pre[i - 1 ][j]
for i in range (Q):
l = query[i][ 0 ]
r = query[i][ 1 ]
maxi = 0
c = 'a'
for j in range ( 256 ):
times = pre[r][j]
if (l):
times - = pre[l - 1 ][j]
if (times > maxi):
maxi = times
c = chr (j)
print ( "Query " , i + 1 , ": " , c)
Str = "striver"
query = [[ 0 , 1 ], [ 1 , 6 ], [ 5 , 6 ]]
solveQueries( Str , query)
|
C#
using System;
class GFG
{
static void solveQueries(String str,
int [,] query)
{
int len = str.Length;
int Q = query.GetLength(0);
int [,] pre = new int [len, 26];
for ( int i = 0; i < len; i++)
{
pre[i, str[i] - 'a' ]++;
if (i > 0)
{
for ( int j = 0; j < 26; j++)
pre[i, j] += pre[i - 1, j];
}
}
for ( int i = 0; i < Q; i++)
{
int l = query[i, 0];
int r = query[i, 1];
int maxi = 0;
char c = 'a' ;
for ( int j = 0; j < 26; j++)
{
int times = pre[r, j];
if (l > 0)
times -= pre[l - 1, j];
if (times > maxi)
{
maxi = times;
c = ( char )( 'a' + j);
}
}
Console.WriteLine( "Query" + (i + 1) + ": " + c);
}
}
public static void Main(String[] args)
{
String str = "striver" ;
int [,] query = {{0, 1}, {1, 6}, {5, 6}};
solveQueries(str, query);
}
}
|
Javascript
<script>
function solveQueries(str,query)
{
let len = str.length;
let Q = query.length;
let pre = new Array(len);
for (let i=0;i<len;i++)
{
pre[i]= new Array(26);
for (let j=0;j<26;j++)
{
pre[i][j]=0;
}
}
for (let i = 0; i < len; i++)
{
pre[i][str[i].charCodeAt(0) - 'a' .charCodeAt(0)]++;
if (i > 0)
{
for (let j = 0; j < 26; j++)
pre[i][j] += pre[i - 1][j];
}
}
for (let i = 0; i < Q; i++)
{
let l = query[i][0];
let r = query[i][1];
let maxi = 0;
let c = 'a' ;
for (let j = 0; j < 26; j++)
{
let times = pre[r][j];
if (l > 0)
times -= pre[l - 1][j];
if (times > maxi)
{
maxi = times;
c = String.fromCharCode( 'a' .charCodeAt(0) + j);
}
}
document.write( "Query" + (i + 1) + ": " + c+ "<br>" );
}
}
let str = "striver" ;
let query = [[0, 1], [1, 6], [5, 6]];
solveQueries(str, query);
</script>
|
Output:
Query 1: s
Query 2: r
Query 3: e
Time Complexity: O(26*N), as we are using nested loops for traversing 26*N times. Where N is the length of the string.
Auxiliary Space: O(26*N), as we are using extra space for the matrix pre. Where N is the length of the string.