Queries to print the character that occurs the maximum number of times in a given range

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.

Efficient Approach: An efficient approach is to use a prefix sum array to efficiently answer the query. Let pre[i][j] stores the occurence of a character j till the i-th index. For every query ocuurence 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the sum of
// the addition of all possible subsets.
#include <bits/stdc++.h>
using namespace std;
  
// Function that answers all the queries
void solveQueries(string str, vector<vector<int> >& query)
{
  
    // Length of the string
    int len = str.size();
  
    // Number of queries
    int Q = query.size();
  
    // Prefix array
    int pre[len][26];
    memset(pre, 0, sizeof pre);
  
    // Iterate for all the characters
    for (int i = 0; i < len; i++) {
  
        // Increase the count of the character
        pre[i][str[i] - 'a']++;
  
        // Presum array for
        // all 26 characters
        if (i) {
            // Update the prefix array
            for (int j = 0; j < 26; j++)
                pre[i][j] += pre[i - 1][j];
        }
    }
  
    // Answer every query
    for (int i = 0; i < Q; i++) {
        // Range
        int l = query[i][0];
        int r = query[i][1];
        int maxi = 0;
        char c = 'a';
  
        // Iterate for all characters
        for (int j = 0; j < 26; j++) {
            // Times the lowercase character
            // j occurs till r-th index
            int times = pre[r][j];
  
            // Subtract the times it occurred
            // till (l-1)th index
            if (l)
                times -= pre[l - 1][j];
  
            // Max times it occurs
            if (times > maxi) {
                maxi = times;
                c = char('a' + j);
            }
        }
        // Print the answer
        cout << "Query " << i + 1 << ": " << c << endl;
    }
}
// Driver Code
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);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the sum of 
// the addition of all possible subsets.
class GFG 
{
      
    // Function that answers all the queries
    static void solveQueries(String str, 
                             int[][] query)
    {
          
        // Length of the string
        int len = str.length();
          
        // Number of queries
        int Q = query.length;
          
        // Prefix array
        int[][] pre = new int[len][26];
          
        // Iterate for all the characters
        for (int i = 0; i < len; i++)
        {
              
            // Increase the count of the character
            pre[i][str.charAt(i) - 'a']++;
              
            // Presum array for 
            // all 26 characters
            if (i > 0)
            {
                  
                // Update the prefix array
                for (int j = 0; j < 26; j++) 
                    pre[i][j] += pre[i - 1][j];
            }
        }
          
        // Answer every query
        for (int i = 0; i < Q; i++)
        {
              
            // Range
            int l = query[i][0]; 
            int r = query[i][1]; 
            int maxi = 0
            char c = 'a';
              
            // Iterate for all characters
            for (int j = 0; j < 26; j++)
            {
                  
                // Times the lowercase character 
                // j occurs till r-th index
                int times = pre[r][j];
                  
                // Subtract the times it occurred 
                // till (l-1)th index
                if (l > 0)
                    times -= pre[l - 1][j];
                  
                // Max times it occurs
                if (times > maxi) 
                
                    maxi = times; 
                    c = (char)('a' + j); 
                }
            }
              
            // Print the answer
            System.out.println("Query" + (i + 1) + ": " + c);
        }
    }
  
    // Driver Code
    public static void main(String[] args) 
    {
        String str = "striver";
        int[][] query = {{0, 1}, {1, 6}, {5, 6}};
        solveQueries(str, query);
    }
}
  
// This code is contributed by
// sanjeev2552

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the sum of
# the addition of all possible subsets.
  
# Function that answers all the queries
def solveQueries(Str, query):
  
    # Length of the String
    ll = len(Str)
  
    # Number of queries
    Q = len(query)
  
    # Prefix array
    pre = [[0 for i in range(256)] 
              for i in range(ll)]
    # memset(pre, 0, sizeof pre)
  
    # Iterate for all the characters
    for i in range(ll):
  
        # Increase the count of the character
        pre[i][ord(Str[i])] += 1
  
        # Presum array for
        # all 26 characters
        if (i):
              
            # Update the prefix array
            for j in range(256):
                pre[i][j] += pre[i - 1][j]
  
    # Answer every query
    for i in range(Q):
          
        # Range
        l = query[i][0]
        r = query[i][1]
        maxi = 0
        c = 'a'
  
        # Iterate for all characters
        for j in range(256):
              
            # Times the lowercase character
            # j occurs till r-th index
            times = pre[r][j]
  
            # Subtract the times it occurred
            # till (l-1)th index
            if (l):
                times -= pre[l - 1][j]
  
            # Max times it occurs
            if (times > maxi):
                maxi = times
                c = chr(j)
  
        # Print the answer
        print("Query ", i + 1, ": ", c)
  
# Driver Code
Str = "striver"
query = [[0, 1], [1, 6], [5, 6]]
solveQueries(Str, query)
  
# This code is contributed by Mohit Kumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the sum of 
// the addition of all possible subsets.
using System;
  
class GFG 
{
      
    // Function that answers all the queries
    static void solveQueries(String str, 
                             int[,] query)
    {
          
        // Length of the string
        int len = str.Length;
          
        // Number of queries
        int Q = query.GetLength(0);
          
        // Prefix array
        int[,] pre = new int[len, 26];
          
        // Iterate for all the characters
        for (int i = 0; i < len; i++)
        {
              
            // Increase the count of the character
            pre[i, str[i] - 'a']++;
              
            // Presum array for 
            // all 26 characters
            if (i > 0)
            {
                  
                // Update the prefix array
                for (int j = 0; j < 26; j++) 
                    pre[i, j] += pre[i - 1, j];
            }
        }
          
        // Answer every query
        for (int i = 0; i < Q; i++)
        {
              
            // Range
            int l = query[i, 0]; 
            int r = query[i, 1]; 
            int maxi = 0; 
            char c = 'a';
              
            // Iterate for all characters
            for (int j = 0; j < 26; j++)
            {
                  
                // Times the lowercase character 
                // j occurs till r-th index
                int times = pre[r, j];
                  
                // Subtract the times it occurred 
                // till (l-1)th index
                if (l > 0)
                    times -= pre[l - 1, j];
                  
                // Max times it occurs
                if (times > maxi) 
                
                    maxi = times; 
                    c = (char)('a' + j); 
                }
            }
              
            // Print the answer
            Console.WriteLine("Query" + (i + 1) + ": " + c);
        }
    }
  
    // Driver Code
    public static void Main(String[] args) 
    {
        String str = "striver";
        int[,] query = {{0, 1}, {1, 6}, {5, 6}};
        solveQueries(str, query);
    }
}
  
// This code is contributed by Princi Singh

chevron_right


Output:

Query 1: s
Query 2: r
Query 3: e


My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.





Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.