# Queries for Nth smallest character for a given range in a string

Given a string **str** which consists of only lowercase letters and an array **arr[][]** that represents range queries on the given string str where each query contains 3 integers, {L, R, N} such that for each query we have to output the N^{th} smallest character in the given range [L, R] as specified in the query.

**Examples:**

Input:str = “afbccdeb”, arr[][] = {{2, 4, 1}, {1, 6, 4}, {1, 8, 7}}

Output:b c e

Explanation:

1^{st}smallest character in range [2, 4] or in the sub-string “fbc” is ‘b’

4^{th}smallest character in range [1, 6] or in the sub-string “afbccd” is ‘c’

7^{th}smallest character in range [1, 8] or in the whole string is ‘e’

Input:str = “geeksforgeeks”, arr[][] = {{1, 4, 2}, {3, 7, 3}, {4, 13, 4}}

Output:e k g

Explanation:

2^{nd}smallest character in range [1, 4] or in the sub-string “geek” is ‘e’

3^{rd}smallest character in range [3, 7] or in the sub-string “eksfo” is ‘k’

4^{th}smallest character in range [4, 13] or in the sub-string “sforgeeks”is ‘g’

**Naive Approach:** A naive approach is to run a loop from **L** to **R** and generate a substring in this range. Once the substring is found, sort the substring to find N^{th} character in the sorted string.

**Time Complexity Analysis:**

- In the worst case, traversing from
**L**to**R**will have a complexity of**O(N)**. - Sorting a substring takes a complexity of
**O(N * Log(N))**. - Since we are sorting the substring for every query, therefore, the overall time complexity is
**O(N**.^{2}* Log(N))

**Efficient Approach:** The idea is to make use of a two-dimensional hash table. The hash table **H[][]** is initialized for **N rows** and **26 columns** where N represents the length of the string and 26 as there are a total of 26 lowercase letters.

The idea behind hashtable is that for each index **i** where ‘i’ ranges from 1 to N, we keep a track of the number of occurrence of each of the 26 lowercase letters on or before the **i ^{th}** index. To do this, hashing is used where each character is treated as a number in the following way:

'a' -> 0 'b' -> 1 . . . 'z' -> 25

Therefore, for each query {L, R, N}, we get the occurrence of each character for the given range by subtracting the elements of **H[L – 1][j]** from **H[R][j]** where j ranges from 0 to 25 in the form of a hash table. After this, all we need to do is traverse from 0 to 25 and add the contents of the resultant array. Whenever the sum is equal to or exceeds **N**, the character representing that index is the required answer.

For example, if on 5^{th} index(j = 4), the sum till then exceeds N, the answer becomes ‘e’ as 4 is equivalent to the character ‘e’. Below is the pictorial representation of the sample case:

The image describes the hashtable corresponding to the given string. For range **[2, 4]**, we perform subtraction of the contents from **H[2 – 1]** from **H[4]**. We get:

Clearly this resultant array contains the count of elements that are within the range [2, 4]. So we simply traverse from 0 to 25 and count the contents until we reach N. In the query for N = 1 the answer is ‘b’, for N = 2 the answer becomes ‘c’ and so on.

Below is the implementation of the above approach:

## C++

`// C++ implementation to find the Nth ` `// smallest character in a given range ` `// of a string ` ` ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Query structure to represent a query range ` `// along with n ` `struct` `Query { ` ` ` `int` `l, r, n; ` `}; ` ` ` `// Function to print the Nth smallest ` `// character for a given range in a string ` `int` `findSmallest(string s, Query q[], ` `int` `m) ` `{ ` ` ` ` ` `// Integer N contains the ` ` ` `// length of the string s ` ` ` `int` `N = s.length(); ` ` ` ` ` `// We initialise our hash array and ` ` ` `// set all the elements to 0 ` ` ` `int` `H[N + 1][26]; ` ` ` `memset` `(H, 0, ` `sizeof` `(H)); ` ` ` ` ` `// We preprocess our string in which we ` ` ` `// update the current character ` ` ` `// as well as add the H[i - 1]th ` ` ` `// array to H[i] ` ` ` `for` `(` `int` `i = 1; i <= N; i++) { ` ` ` ` ` `// Incrementing the frequency of ` ` ` `// ith row based on the occurrence ` ` ` `// of the characters up to i-th index ` ` ` `++H[i][s[i - 1] - ` `'a'` `]; ` ` ` ` ` `// Adding the values of the array at ` ` ` `// the previous index to the next index ` ` ` `for` `(` `int` `j = 0; j < 26; j++) { ` ` ` `H[i][j] += H[i - 1][j]; ` ` ` `} ` ` ` `} ` ` ` ` ` `// We traverse from 0 to m to ` ` ` `// fetch all the queries ` ` ` `for` `(` `int` `j = 0; j < m; j++) { ` ` ` ` ` `// Extracting L, R and N ` ` ` `// from the query array q ` ` ` `int` `l = q[j].l, r = q[j].r, ` ` ` `n = q[j].n; ` ` ` ` ` `// The initial sum is set to 0 ` ` ` `int` `sum = 0; ` ` ` ` ` `// We subtract H[l-1] from h[r] ` ` ` `// and add it to the sum ` ` ` `for` `(` `int` `i = 0; i < 26; i++) { ` ` ` `sum += H[r][i] - H[l - 1][i]; ` ` ` ` ` `// Whenever the sum is greater than ` ` ` `// or equal to N, the equivalent ` ` ` `// character of the index is our ` ` ` `// nth smallest character ` ` ` `if` `(sum >= n) { ` ` ` `cout << (` `char` `)(` `'a'` `+ i) << ` `"\n"` `; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `// Input string s ` ` ` `string s = ` `"afbccdeb"` `; ` ` ` `// Query array q, for each q ` ` ` `// it contains l, r and n ` ` ` `Query q[] = { { 2, 4, 1 }, ` ` ` `{ 1, 6, 4 }, ` ` ` `{ 1, 8, 7 } }; ` ` ` `int` `x = ` `sizeof` `(q) / ` `sizeof` `(q[0]); ` ` ` ` ` `findSmallest(s, q, x); ` `} ` |

*chevron_right*

*filter_none*

## Java

`// JAVA implementation to find the Nth ` `// smallest character for a given range ` `// in a string ` ` ` `import` `java.io.*; ` `import` `java.util.*; ` ` ` `class` `GFG { ` ` ` ` ` `// Query class to represent a query range ` ` ` `// along with n ` ` ` `public` `static` `class` `Query { ` ` ` `public` `int` `l, r, n; ` ` ` ` ` `// Constructor for the Query class which ` ` ` `// takes three integers L, R, N ` ` ` `public` `Query(` `int` `l, ` `int` `r, ` `int` `n) ` ` ` `{ ` ` ` `this` `.l = l; ` ` ` `this` `.r = r; ` ` ` `this` `.n = n; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Function to print the Nth smallest ` ` ` `// character for a given range in a string ` ` ` `public` `static` `void` `printSmallest(String s, Query[] q) ` ` ` `{ ` ` ` ` ` `// Integer N contains the ` ` ` `// length of the string s ` ` ` `int` `N = s.length(); ` ` ` ` ` `// We initialise our hash array and ` ` ` `// set all the elements to 0 ` ` ` `int` `[][] H = ` `new` `int` `[N + ` `1` `][` `26` `]; ` ` ` ` ` `// We preprocess our string in which we ` ` ` `// update the current character ` ` ` `// as well as add the H[i - 1]th ` ` ` `// array to H[i] ` ` ` `for` `(` `int` `i = ` `1` `; i <= N; i++) { ` ` ` ` ` `// Incrementing the frequency of ` ` ` `// ith row based on the occurrence ` ` ` `// of the characters up to i-th index ` ` ` `++H[i][s.charAt(i - ` `1` `) - ` `'a'` `]; ` ` ` ` ` `// Adding the values of the array at ` ` ` `// the previous index to the next index ` ` ` `for` `(` `int` `j = ` `0` `; j < ` `26` `; j++) { ` ` ` `H[i][j] += H[i - ` `1` `][j]; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Integer m contains the ` ` ` `// number of queries ` ` ` `int` `m = q.length; ` ` ` ` ` `// We traverse from 0 to m to ` ` ` `// fetch all the queries ` ` ` `for` `(` `int` `j = ` `0` `; j < m; j++) { ` ` ` ` ` `// Extracting l, r and n ` ` ` `// from the query array q ` ` ` `int` `l = q[j].l, r = q[j].r, ` ` ` `n = q[j].n; ` ` ` ` ` `// The initial sum is set to 0 ` ` ` `int` `sum = ` `0` `; ` ` ` ` ` `// We subtract H[l-1] from h[r] ` ` ` `// and add it to the sum ` ` ` `for` `(` `int` `i = ` `0` `; i < ` `26` `; i++) { ` ` ` `sum += H[r][i] - H[l - ` `1` `][i]; ` ` ` ` ` `// Whenever the sum is greater than ` ` ` `// or equal to N, the equivalent ` ` ` `// character of the index is our ` ` ` `// nth smallest character ` ` ` `if` `(sum >= n) { ` ` ` `System.out.println((` `char` `)(` `'a'` `+ i)); ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `main(String args[]) ` ` ` `{ ` ` ` `// Input string s ` ` ` `String s = ` `"afbccdeb"` `; ` ` ` ` ` `// Query array q, for each q ` ` ` `// it contains l, r and n ` ` ` `Query[] q = { ` `new` `Query(` `2` `, ` `4` `, ` `1` `), ` ` ` `new` `Query(` `1` `, ` `6` `, ` `4` `), ` ` ` `new` `Query(` `1` `, ` `8` `, ` `7` `) }; ` ` ` ` ` `// Calling the function ` ` ` `printSmallest(s, q); ` ` ` `} ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 implementation to find the Nth ` `# smallest character in a given range ` `# of a string ` ` ` `# Function to print the Nth smallest ` `# character for a given range in a string ` `def` `findSmallest(s, q, m): ` ` ` ` ` `# Integer N contains the ` ` ` `# length of the s ` ` ` `N ` `=` `len` `(s) ` ` ` ` ` `# We initialise our hash array and ` ` ` `# set all the elements to 0 ` ` ` `H ` `=` `[[` `0` `for` `i ` `in` `range` `(` `26` `)]` `for` `i ` `in` `range` `(N ` `+` `1` `)] ` ` ` ` ` `# We preprocess our in which we ` ` ` `# update the current character ` ` ` `# as well as add the H[i - 1]th ` ` ` `# array to H[i] ` ` ` `for` `i ` `in` `range` `(` `1` `, N ` `+` `1` `): ` ` ` ` ` `# Incrementing the frequency of ` ` ` `# ith row based on the occurrence ` ` ` `# of the characters up to i-th index ` ` ` `H[i][` `ord` `(s[i ` `-` `1` `]) ` `-` `ord` `(` `'a'` `)] ` `+` `=` `1` ` ` ` ` `# Adding the values of the array at ` ` ` `# the previous index to the next index ` ` ` `for` `j ` `in` `range` `(` `26` `): ` ` ` `H[i][j] ` `+` `=` `H[i ` `-` `1` `][j] ` ` ` ` ` `# We traverse from 0 to m to ` ` ` `# fetch all the queries ` ` ` `for` `j ` `in` `range` `(m): ` ` ` ` ` `# Extracting L, R and N ` ` ` `# from the query array q ` ` ` `l ` `=` `q[j][` `0` `] ` ` ` `r ` `=` `q[j][` `1` `] ` ` ` `n ` `=` `q[j][` `2` `] ` ` ` ` ` `# The initial sum is set to 0 ` ` ` `sum` `=` `0` ` ` ` ` `# We subtract H[l-1] from h[r] ` ` ` `# and add it to the sum ` ` ` `for` `i ` `in` `range` `(` `26` `): ` ` ` `sum` `+` `=` `H[r][i] ` `-` `H[l ` `-` `1` `][i] ` ` ` ` ` `# Whenever the sum is greater than ` ` ` `# or equal to N, the equivalent ` ` ` `# character of the index is our ` ` ` `# nth smallest character ` ` ` `if` `(` `sum` `>` `=` `n): ` ` ` `print` `(` `chr` `(` `ord` `(` `'a'` `) ` `+` `i)) ` ` ` `break` ` ` `# Driver code ` `if` `__name__ ` `=` `=` `'__main__'` `: ` ` ` ` ` `# Input s ` ` ` `s ` `=` `"afbccdeb"` ` ` ` ` `# Query array q, for each q ` ` ` `# it contains l, r and n ` ` ` `q ` `=` `[ [ ` `2` `, ` `4` `, ` `1` `], ` ` ` `[ ` `1` `, ` `6` `, ` `4` `], ` ` ` `[ ` `1` `, ` `8` `, ` `7` `] ] ` ` ` `x ` `=` `len` `(q) ` ` ` ` ` `findSmallest(s, q, x) ` ` ` `# This code is contributed by mohit kumar 29 ` |

*chevron_right*

*filter_none*

## C#

`// C# implementation to find the Nth ` `// smallest character for a given range ` `// in a string ` `using` `System; ` ` ` `class` `GFG { ` ` ` ` ` `// Query class to represent a query range ` ` ` `// along with n ` ` ` `public` `class` `Query { ` ` ` `public` `int` `l, r, n; ` ` ` ` ` `// Constructor for the Query class which ` ` ` `// takes three integers L, R, N ` ` ` `public` `Query(` `int` `l, ` `int` `r, ` `int` `n) ` ` ` `{ ` ` ` `this` `.l = l; ` ` ` `this` `.r = r; ` ` ` `this` `.n = n; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Function to print the Nth smallest ` ` ` `// character for a given range in a string ` ` ` `public` `static` `void` `printSmallest(String s, Query[] q) ` ` ` `{ ` ` ` ` ` `// int N contains the ` ` ` `// length of the string s ` ` ` `int` `N = s.Length; ` ` ` ` ` `// We initialise our hash array and ` ` ` `// set all the elements to 0 ` ` ` `int` `[,] H = ` `new` `int` `[N + 1,26]; ` ` ` ` ` `// We preprocess our string in which we ` ` ` `// update the current character ` ` ` `// as well as add the H[i - 1]th ` ` ` `// array to H[i] ` ` ` `for` `(` `int` `i = 1; i <= N; i++) { ` ` ` ` ` `// Incrementing the frequency of ` ` ` `// ith row based on the occurrence ` ` ` `// of the characters up to i-th index ` ` ` `++H[i, s[i - 1] - ` `'a'` `]; ` ` ` ` ` `// Adding the values of the array at ` ` ` `// the previous index to the next index ` ` ` `for` `(` `int` `j = 0; j < 26; j++) { ` ` ` `H[i, j] += H[i - 1, j]; ` ` ` `} ` ` ` `} ` ` ` ` ` `// int m contains the ` ` ` `// number of queries ` ` ` `int` `m = q.Length; ` ` ` ` ` `// We traverse from 0 to m to ` ` ` `// fetch all the queries ` ` ` `for` `(` `int` `j = 0; j < m; j++) { ` ` ` ` ` `// Extracting l, r and n ` ` ` `// from the query array q ` ` ` `int` `l = q[j].l, r = q[j].r, ` ` ` `n = q[j].n; ` ` ` ` ` `// The initial sum is set to 0 ` ` ` `int` `sum = 0; ` ` ` ` ` `// We subtract H[l-1] from h[r] ` ` ` `// and add it to the sum ` ` ` `for` `(` `int` `i = 0; i < 26; i++) { ` ` ` `sum += H[r, i] - H[l - 1, i]; ` ` ` ` ` `// Whenever the sum is greater than ` ` ` `// or equal to N, the equivalent ` ` ` `// character of the index is our ` ` ` `// nth smallest character ` ` ` `if` `(sum >= n) { ` ` ` `Console.WriteLine((` `char` `)(` `'a'` `+ i)); ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `Main(String []args) ` ` ` `{ ` ` ` `// Input string s ` ` ` `String s = ` `"afbccdeb"` `; ` ` ` ` ` `// Query array q, for each q ` ` ` `// it contains l, r and n ` ` ` `Query[] q = { ` `new` `Query(2, 4, 1), ` ` ` `new` `Query(1, 6, 4), ` ` ` `new` `Query(1, 8, 7) }; ` ` ` ` ` `// Calling the function ` ` ` `printSmallest(s, q); ` ` ` `} ` `} ` ` ` `// This code is contributed by Rajput-Ji ` |

*chevron_right*

*filter_none*

**Output:**

b c e

**Time Complexity Analysis:**

- For the above approach, though the preprocessing consists of two loops, the second loop runs for a constant number of times(26). Therefore, the time taken for preprocessing is
**O(N)**. - After preprocessing, for every query, the character is returned in constant time as again here the for loop runs a constant number of times(26). Therefore, the time taken for answering each query is
**O(1)**.

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: **DSA Self Paced**. Become industry ready at a student-friendly price.

## Recommended Posts:

- Queries to find total number of duplicate character in range L to R in the string S
- Queries to print the character that occurs the maximum number of times in a given range
- Queries to find the first non-repeating character in the sub-string of a string
- Queries to find the last non-repeating character in the sub-string of a given string
- Lexicographically smallest string formed by appending a character from first K characters of a string | Set 2
- Lexicographically smallest string formed by appending a character from the first K characters of a given string
- String Range Queries to find the number of subsets equal to a given String
- Queries for rotation and Kth character of the given string in constant time
- Queries to answer the X-th smallest sub-string lexicographically
- Lexicographically smallest string formed by removing at most one character
- Make the string lexicographically smallest and non palindromic by replacing exactly one character
- String Range Queries to count number of distinct characters with updates
- Find a string such that every character is lexicographically greater than its immediate next character
- Modify the string such that every character gets replaced with the next character in the keyboard
- Replace every character of string by character whose ASCII value is K times more than it
- Check if frequency of character in one string is a factor or multiple of frequency of same character in other string
- Map every character of one string to another such that all occurrences are mapped to the same character
- Smallest alphabet greater than a given character
- Two equal sum segment range queries
- Replace every character of a string by a different character

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.