Queries to count frequencies of a given character in a given range of indices

Given a string S of length N and an array Q[][] of queries in the form {l, r, y}. For each query, the task is to print the number of characters y present in the range [l, r].

Examples:

Input: S = “aabv”, Q[][] = {{0, 3, ‘a’}, {1, 2, ‘b’}}
Output: 2 1
Explanation:
Query 1: Number of character ‘a’ present in the range [0, 3] is 2.
Query 2: Number of character ‘b’ present in the range [1, 2] is 1.

Input: S = “abcd”, Q[][] = {{1, 3, ‘c’}, {1, 1, ‘b’}}
Output: 1 1
Explanation:
Query 1: Number of character ‘c’ present in the range [1, 3] is 1.
Query 2: Number of character ‘b’ present in the range [1, 1] is 1.

Naive Approach: The simplest approach is to traverse the string over the range [l, r] and increment the counter by 1 if the character at index i is equal to y for each query {l, r, y}. After traversing, print the counter for each query.
Time Complexity: O(N*Q)
Auxiliary Space: O(N)

Efficient Approach: The idea is to pre-compute the number of characters present in the range 1 to i for each character from ‘a’ to ‘z’ where 1 ≤ i ≤ N using Prefix Sum technique. Follow the steps below to solve the problem:



  1. Initialize an array dp[N+1][26] where dp[i][j] stores the number of characters (i+’a’) present in the range [0, i].
  2. Now, Precompute the number of each character present in the range [1, i] where 1 ≤ i ≤ N by incrementing dp[i][j] by dp[i – 1][j] where 0 ≤ j < 26 and increment dp[i][S[j] – ‘a’] by 1.
  3. For each query {l, r, y}, print the value of dp[r][y – ‘a’] – dp[l – 1][y – ‘a’] as the number of characters y present in the range [l, r].

Below is the implementation of the above approach:

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
  
import java.io.*;
  
class GFG {
  
    // Function to print count of char
    // y present in the range [l, r]
    static void noOfChars(String s,
                          char[][] queries)
    {
  
        // Length of the string
        int n = s.length();
  
        // Stores the precomputed results
        int dp[][] = new int[n + 1][26];
  
        // Iterate the given string
        for (int i = 0; i < n; i++) {
  
            // Increment dp[i][y-'a'] by 1
            dp[i + 1][s.charAt(i) - 'a']++;
  
            // Pre-compute
            for (int j = 0; j < 26; j++) {
                dp[i + 1][j] += dp[i][j];
            }
        }
  
        // Number of queries
        int q = queries.length;
  
        // Traverse each query
        for (int i = 0; i < q; i++) {
  
            int l = (int)queries[i][0];
            int r = (int)queries[i][1];
            int c = queries[i][2] - 'a';
  
            // Print the result for
            // each query
            System.out.print(
                dp[r] - dp[l - 1]
                + " ");
        }
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        // Given string
        String S = "aabv";
  
        // Given Queries
        char queries[][]
            = new char[][] { { 1, 2, 'a' },
                             { 2, 3, 'b' } };
  
        // Function Call
        noOfChars(S, queries);
    }
}

chevron_right


Output:

2 1

Time Complexity: O(Q+N*26)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.