# Index of character depending on frequency count in string

• Last Updated : 08 Jun, 2021

Given a string str containing only lowercase characters, the task is to answer Q queries of the following type:

1. 1 C X: Find the largest i such that str[0…i] has exactly X occurrence of the character C.
2. 2 C X: Find the smallest i such that str[0…i] has exactly X occurrence of the character C.

Example:

Input: str = “geeksforgeeks”, query[] = {{1, ‘e’, 2}, {2, ‘k’, 2}}
Output:

11
Query 1: “geeksforg” is the largest substring starting at str[0] with ‘e’ appearing exactly twice and the index of the last character is 8.
Query 2: “geeksforgeek” is the smallest substring starting at str[0] with ‘k’ appearing exactly twice and the index of the last character is 11.
Input: str = “abcdabcd”, query[] = {{1, ‘a’, 1}, {2, ‘a’, 2}}
Output:

Approach: Create two 2-dimensional arrays L[][] and F[][] such that L[i][j] stores the largest i such that the ith character appears exactly jth times in str[0…i] and F[i][j] stores the smallest i such that the ith character appears exactly jth times in str[0…i]. In order to do so, traverse the whole string and maintain a frequency array so that for each iteration/character, its count is updated and then start another loop from 0 to 26 (each letter a-z). In the inner loop, if the iterator is equal to character value then update L[][] and F[][] array with the current index position using outer loop iterator otherwise just increment the L[][] array value for other characters by 1 as only index has been incremented and the character has not occurred. Now, type 1 query can be answered as L[given character][Frequency count] and type 2 query as F[given character][Frequency count].
Below is the implementation of the above approach.

## C++

 // C++ implementation of the approach#include using namespace std; const int MAX = 26; // Function to perform the queriesvoid performQueries(string str, int q, int type[],                    char ch[], int freq[]){     int n = str.length();     // L[i][j] stores the largest i    // such that ith character appears    // exactly jth times in str[0...i]    int L[MAX][n];     // F[i][j] stores the smallest i    // such that ith character appears    // exactly jth times in str[0...i]    int F[MAX][n];     // To store the frequency of each    // of the character of str    int cnt[MAX] = { 0 };    for (int i = 0; i < n; i++) {         // Current character of str        int k = str[i] - 'a';         // Update its frequency        cnt[k]++;         // For every lowercase character        // of the English alphabet        for (int j = 0; j < MAX; j++) {             // If it is equal to the character            // under consideration then update            // L[][] and R[][] as it is cnt[j]th            // occurrence of character k            if (k == j) {                L[j][cnt[j]] = i;                F[j][cnt[j]] = i;            }             // Only update L[][] as k has not            // been occurred so only index            // has to be incremented            else                L[j][cnt[j]] = L[j][cnt[j]] + 1;        }    }     // Perform the queries    for (int i = 0; i < q; i++) {         // Type 1 query        if (type[i] == 1) {            cout << L[ch[i] - 'a'][freq[i]];        }         // Type 2 query        else {            cout << F[ch[i] - 'a'][freq[i]];        }         cout << "\n";    }} // Driver codeint main(){    string str = "geeksforgeeks";     // Queries    int type[] = { 1, 2 };    char ch[] = { 'e', 'k' };    int freq[] = { 2, 2 };    int q = sizeof(type) / sizeof(int);     // Perform the queries    performQueries(str, q, type, ch, freq);     return 0;}

## Java

 // Java implementation of the approachclass GFG{static int MAX = 26; // Function to perform the queriesstatic void performQueries(String str, int q, int type[],                                   char ch[], int freq[]){    int n = str.length();     // L[i][j] stores the largest i    // such that ith character appears    // exactly jth times in str[0...i]    int [][]L = new int[MAX][n];     // F[i][j] stores the smallest i    // such that ith character appears    // exactly jth times in str[0...i]    int [][]F = new int[MAX][n];     // To store the frequency of each    // of the character of str    int []cnt = new int[MAX];    for (int i = 0; i < n; i++)    {         // Current character of str        int k = str.charAt(i) - 'a';         // Update its frequency        cnt[k]++;         // For every lowercase character        // of the English alphabet        for (int j = 0; j < MAX; j++)        {             // If it is equal to the character            // under consideration then update            // L[][] and R[][] as it is cnt[j]th            // occurrence of character k            if (k == j)            {                L[j][cnt[j]] = i;                F[j][cnt[j]] = i;            }             // Only update L[][] as k has not            // been occurred so only index            // has to be incremented            else                L[j][cnt[j]] = L[j][cnt[j]] + 1;        }    }     // Perform the queries    for (int i = 0; i < q; i++)    {         // Type 1 query        if (type[i] == 1)        {            System.out.print(L[ch[i] - 'a'][freq[i]]);        }         // Type 2 query        else        {            System.out.print(F[ch[i] - 'a'][freq[i]]);        }        System.out.print("\n");    }} // Driver codepublic static void main(String []args){    String str = "geeksforgeeks";     // Queries    int type[] = { 1, 2 };    char ch[] = { 'e', 'k' };    int freq[] = { 2, 2 };    int q = type.length;     // Perform the queries    performQueries(str, q, type, ch, freq);}} // This code is contributed by Rajput-Ji

## Python3

 # Python3 implementation of the approachimport numpy as np MAX = 26; # Function to perform the queriesdef performQueries(string , q, type_arr, ch, freq) :     n = len(string);     # L[i][j] stores the largest i    # such that ith character appears    # exactly jth times in str[0...i]    L = np.zeros((MAX, n));     # F[i][j] stores the smallest i    # such that ith character appears    # exactly jth times in str[0...i]    F = np.zeros((MAX, n));     # To store the frequency of each    # of the character of str    cnt = [ 0 ] * MAX;    for i in range(n) :         # Current character of str        k = ord(string[i]) - ord('a');         # Update its frequency        cnt[k] += 1;         # For every lowercase character        # of the English alphabet        for j in range(MAX) :             # If it is equal to the character            # under consideration then update            # L[][] and R[][] as it is cnt[j]th            # occurrence of character k            if (k == j) :                L[j][cnt[j]] = i;                F[j][cnt[j]] = i;             # Only update L[][] as k has not            # been occurred so only index            # has to be incremented            else :                L[j][cnt[j]] = L[j][cnt[j]] + 1;     # Perform the queries    for i in range(q) :         # Type 1 query        if (type_arr[i] == 1) :            print(L[ord(ch[i]) -                    ord('a')][freq[i]], end = "");         # Type 2 query        else :            print(F[ord(ch[i]) -                    ord('a')][freq[i]], end = "");                     print()         # Driver codeif __name__ == "__main__" :     string = "geeksforgeeks";     # Queries    type_arr = [ 1, 2 ];    ch = [ 'e', 'k' ];    freq = [ 2, 2 ];    q = len(type_arr);     # Perform the queries    performQueries(string, q, type_arr, ch, freq); # This code is contributed by AnkitRai01

## C#

 // C# implementation of the approachusing System; class GFG{static int MAX = 26; // Function to perform the queriesstatic void performQueries(String str, int q, int []type,                                     char []ch, int []freq){    int n = str.Length;     // L[i,j] stores the largest i    // such that ith character appears    // exactly jth times in str[0...i]    int [,]L = new int[MAX, n];     // F[i,j] stores the smallest i    // such that ith character appears    // exactly jth times in str[0...i]    int [,]F = new int[MAX, n];     // To store the frequency of each    // of the character of str    int []cnt = new int[MAX];    for (int i = 0; i < n; i++)    {         // Current character of str        int k = str[i] - 'a';         // Update its frequency        cnt[k]++;         // For every lowercase character        // of the English alphabet        for (int j = 0; j < MAX; j++)        {             // If it is equal to the character            // under consideration then update            // L[,] and R[,] as it is cnt[j]th            // occurrence of character k            if (k == j)            {                L[j, cnt[j]] = i;                F[j, cnt[j]] = i;            }             // Only update L[,] as k has not            // been occurred so only index            // has to be incremented            else                L[j, cnt[j]] = L[j, cnt[j]] + 1;        }    }     // Perform the queries    for (int i = 0; i < q; i++)    {         // Type 1 query        if (type[i] == 1)        {            Console.Write(L[ch[i] - 'a', freq[i]]);        }         // Type 2 query        else        {            Console.Write(F[ch[i] - 'a', freq[i]]);        }        Console.Write("\n");    }} // Driver codepublic static void Main(String []args){    String str = "geeksforgeeks";     // Queries    int []type = { 1, 2 };    char []ch = { 'e', 'k' };    int []freq = { 2, 2 };    int q = type.Length;     // Perform the queries    performQueries(str, q, type, ch, freq);}} // This code is contributed by 29AjayKumar

## Javascript



Output:

8
11

Time Complexity: O(n) where n is the length of the string.

My Personal Notes arrow_drop_up