Count of distinct characters in a substring by given range for Q queries - GeeksforGeeks

03 Jun, 2021
Given a string S consisting of lower case alphabets of size N and Q queries in the range [L, R], the task is to print the count of distinct characters in the substring by given range for each query.
Examples: 
Input: S = “geeksforgeeks”, Q[][] = {{0, 4}, {3, 7}} Output: 4 5 Explanation: Distinct characters in substring S[0:4] are ‘g’, ‘e’, ‘k’ and ‘s’ Distinct characters in substring in S[3:7] are ‘k’, ‘s’ ‘f’, ‘o’ and ‘r’
Input: S = “geeksforgeeksisacomputerscienceportal”, Q[][] = {{0, 10}, {15, 18}, {12, 20}} Output: 7 4 8 
Naive Approach: The idea is to use hashing to maintain the frequency of each character in the given substring and then count the characters with a frequency equal to 1.Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ Program for Naive Approach #include <bits/stdc++.h>using namespace std; void findCount(string s, int L, int R){    // counter to count distinct char    int distinct = 0;     // Initializing frequency array to    // count characters as the appear in    // substring S[L:R]    int frequency[26] = {};     // Iterating over S[L] to S[R]    for (int i = L; i <= R; i++) {         // incrementing the count        // of s[i] character in frequency array        frequency[s[i] - 'a']++;    }     for (int i = 0; i < 26; i++) {         // if frequency of any character is > 0        // then increment the counter        if (frequency[i] > 0)            distinct++;    }     cout << distinct << endl;} /* Driver code*/int main(){    string s = "geeksforgeeksisacomputerscienceportal";    int queries = 3;    int Q[queries][2] = { { 0, 10 },                          { 15, 18 },                          { 12, 20 } };     for (int i = 0; i < queries; i++)        findCount(s, Q[i][0], Q[i][1]);     return 0;}
// Java program for the naive approachclass GFG{ static void findCount(String s, int L,                                int R){         // Counter to count distinct char    int distinct = 0;     // Initializing frequency array    // to count characters as the    // appear in subString S[L:R]    int []frequency = new int[26];     // Iterating over S[L] to S[R]    for(int i = L; i <= R; i++)    {               // Incrementing the count of s[i]       // character in frequency array       frequency[s.charAt(i) - 'a']++;    }     for(int i = 0; i < 26; i++)    {               // If frequency of any character       // is > 0 then increment the counter       if (frequency[i] > 0)           distinct++;    }    System.out.print(distinct + "\n");} // Driver codepublic static void main(String[] args){    String s = "geeksforgeeksisa" +               "computerscienceportal";    int queries = 3;    int Q[][] = { { 0, 10 },                  { 15, 18 },                  { 12, 20 } };     for(int i = 0; i < queries; i++)       findCount(s, Q[i][0], Q[i][1]);}} // This code is contributed by sapnasingh4991
# Python3 program for Naive Approach def findCount(s, L, R):         # Counter to count distinct char    distinct = 0     # Initializing frequency array to    # count characters as the appear in    # substring S[L:R]    frequency = [0 for i in range(26)]     # Iterating over S[L] to S[R]    for i in range(L, R + 1, 1):                 # Incrementing the count of s[i]        # character in frequency array        frequency[ord(s[i]) - ord('a')] += 1     for i in range(26):                 # If frequency of any character is > 0        # then increment the counter        if (frequency[i] > 0):            distinct += 1     print(distinct) # Driver codeif __name__ == '__main__':         s = "geeksforgeeksisacomputerscienceportal"    queries = 3    Q = [ [ 0, 10 ],          [ 15, 18 ],          [ 12, 20 ] ]     for i in range(queries):        findCount(s, Q[i][0], Q[i][1]) # This code is contributed by Bhupendra_Singh
// C# program for the naive approachusing System;class GFG{ static void findCount(String s, int L,                                int R){         // Counter to count distinct char    int distinct = 0;     // Initializing frequency array    // to count characters as the    // appear in subString S[L:R]    int []frequency = new int[26];     // Iterating over S[L] to S[R]    for(int i = L; i <= R; i++)    {                 // Incrementing the count of s[i]        // character in frequency array        frequency[s[i] - 'a']++;    }     for(int i = 0; i < 26; i++)    {                     // If frequency of any character        // is > 0 then increment the counter        if (frequency[i] > 0)            distinct++;    }    Console.Write(distinct + "\n");} // Driver codepublic static void Main(String[] args){    String s = "geeksforgeeksisa" +               "computerscienceportal";    int queries = 3;    int [,]Q = {{ 0, 10 },                { 15, 18 },                { 12, 20 }};     for(int i = 0; i < queries; i++)    findCount(s, Q[i, 0], Q[i, 1]);}} // This code is contributed by sapnasingh4991
<script> // Javascript Program for Naive Approach function findCount(s, L, R){    // counter to count distinct char    var distinct = 0;     // Initializing frequency array to    // count characters as the appear in    // substring S[L:R]    var frequency = Array(26).fill(0);     // Iterating over S[L] to S[R]    for (var i = L; i <= R; i++) {         // incrementing the count        // of s[i] character in frequency array        frequency[s[i].charCodeAt(0) - 'a'.charCodeAt(0)]++;    }     for (var i = 0; i < 26; i++) {         // if frequency of any character is > 0        // then increment the counter        if (frequency[i] > 0)            distinct++;    }     document.write( distinct + "<br>");} /* Driver code*/var s = "geeksforgeeksisacomputerscienceportal";var queries = 3;var Q = [ [ 0, 10 ],                      [ 15, 18 ],                      [ 12, 20 ] ];for (var i = 0; i < queries; i++)    findCount(s, Q[i][0], Q[i][1]);  </script>
7
4
8
 
Time Complexity: O(Q×N) 
Efficient Approach: An efficient approach would be to store the position of each character as they appear in the string in an array. For each given query we will iterate over all the 26 lower case alphabets. If the current letter is in the substring S[L: R], then the first element greater than or equal L in the corresponding position vector should exist and be less than or equal to R i.e, there must be a position value between L and R denoting the presence of the alphabet in the query range.For example:
Below is the implementation of the above approach: 
C++
// C++ Program for Efficient Approach// to count the no. of distinct characters// in a substring using STL #include <bits/stdc++.h>using namespace std; // vector of vector to store// position of all characters// as they appear in stringvector<vector<int> > v(26); void build_position_vector(string s){    for (int i = 0; i < s.size(); i++) {         // inserting position of        // character as they appear        v[s[i] - 'a'].push_back(i);    }} void findCount(string s, int L, int R){     build_position_vector(s);     // counter to count distinct char    int distinct = 0;     // iterating over all 26 characters    for (int i = 0; i < 26; i++) {         // Finding the first element        // which is greater than or equal to L        auto first = lower_bound(            v[i].begin(),            v[i].end(), L);         // Check if first pointer exists        // and is less than or equal to R        if (first != v[i].end()            && *first <= R) {            distinct++;        }    }     cout << distinct << endl;} /* Driver code*/int main(){    string s = "geeksforgeeksisacomputerscienceportal";    int queries = 3;    int Q[queries][2] = { { 0, 10 },                          { 15, 18 },                          { 12, 20 } };     for (int i = 0; i < queries; i++)        findCount(s, Q[i][0], Q[i][1]);     return 0;}
7
4
8
 
Time Complexity: O(N + Q logN) 
bgangwar59
sapnasingh4991
Akanksha_Rai
rrrtnx
substring
Algorithms
Arrays
Articles
Competitive Programming
Strings
Arrays
Strings
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
DSA Sheet by Love Babbar
Difference between Informed and Uninformed Search in AI
SCAN (Elevator) Disk Scheduling Algorithms
Quadratic Probing in Hashing
K means Clustering - Introduction
Arrays in Java
Arrays in C/C++
Program for array rotation
Stack Data Structure (Introduction and Program)
Largest Sum Contiguous Subarray