Related Articles
Queries to find Kth greatest character in a range [L, R] from a string with updates
• Last Updated : 22 Oct, 2020

Given a string str of length N, and Q queries of the following two types:

1. (1 L R K): Find the Kth greatest character (non-distinct) from the range of indices [L, R] (1-based indexing)
2. (2 J C): Replace the Jth character from the string by character C.

Examples:

Input: str = “abcddef”, Q = 3, queries[][] = {{1, 2, 5, 3}, {2, 4, g}, {1, 1, 4, 3}}
Output:
c

Explanation :
Query 1: String between indices (2, 5) is “bcdd”. The third largest character is ‘c’. Therefore, c is the required output.
Query 2: Replace S by ‘g’. Therefore, S modifies to “abcgdef”.
Query 3: String between indices (1, 4) is “abcg”. The third largest character is ‘b’. Therefore, b is the required output.

Input: str=” afcdehgk”, Q = 4, queries[][] = {{1, 2, 5, 4}, {2, 5, m}, {1, 3, 7, 2}, {1, 1, 6, 4}}
Output:
c
h
d

Naive Approach: The simplest approach to solve the problem is as follows:

• For each query of type ( 1 L R K ), find the substring of S from the range of indices [L, R], and sort this substring in non-increasing order. Print the character at the Kth index in the substring.
• For each query of type ( 2 J C ), replace the Jth character in S by C.

Time Complexity: O ( Q * ( N log(N) ) ), where N logN is the computational complexity of sorting each substring.
Auxiliary Space: O(N)

The below code is the implementation of the above approach:

## C++

 `// C++ Program to implement``// the above approach` `#include "bits/stdc++.h"``using` `namespace` `std;` `// Function to find the kth greatest``// character from the strijng``char` `find_kth_largest(string str, ``int` `k)``{` `    ``// Sorting the string in``    ``// non-increasing Order``    ``sort(str.begin(), str.end(),``         ``greater<``char``>());``    ``return` `str[k - 1];``}` `// Function to print the K-th character``// from the substring S[l] .. S[r]``char` `printCharacter(string str, ``int` `l,``                    ``int` `r, ``int` `k)``{``    ``// 0-based indexing``    ``l = l - 1;``    ``r = r - 1;` `    ``// Substring of str from the``    ``// indices l to r.``    ``string temp``        ``= str.substr(l, r - l + 1);` `    ``// Extract kth Largest character``    ``char` `ans``        ``= find_kth_largest(temp, k);` `    ``return` `ans;``}` `// Function to replace character at``// pos of str by the character s``void` `updateString(string str, ``int` `pos,``                  ``char` `s)``{``    ``// Index of S to be updated.``    ``int` `index = pos - 1;``    ``char` `c = s;` `    ``// Character to be replaced``    ``// at index in S``    ``str[index] = c;``}` `// Driver Code``int` `main()``{``    ``// Given string``    ``string str = ``"abcddef"``;` `    ``// Count of queries``    ``int` `Q = 3;` `    ``// Queries``    ``cout << printCharacter(str, 1, 2, 2)``         ``<< endl;``    ``updateString(str, 4, ``'g'``);``    ``cout << printCharacter(str, 1, 5, 4)``         ``<< endl;` `    ``return` `0;``}`

## Java

 `// Java Program to implement``// the above approach``//include "bits/stdJava.h"``import` `java.util.*;``class` `GFG{` `// Function to find the kth greatest``// character from the strijng``static` `char` `find_kth_largest(``char` `[]str,``                             ``int` `k)``{``  ``// Sorting the String in``  ``// non-increasing Order``  ``Arrays.sort(str);``  ``reverse(str);``  ``return` `str[k - ``1``];``}``  ``static` `char``[] reverse(``char` `a[])``  ``{``    ``int` `i, n = a.length;``    ``char` `t;``    ``for` `(i = ``0``; i < n / ``2``; i++)``    ``{``      ``t = a[i];``      ``a[i] = a[n - i - ``1``];``      ``a[n - i - ``1``] = t;``    ``}``    ``return` `a;``}``  ` `// Function to print the K-th character``// from the subString S[l] .. S[r]``static` `char` `printCharacter(String str, ``int` `l,``                           ``int` `r, ``int` `k)``{``  ``// 0-based indexing``  ``l = l - ``1``;``  ``r = r - ``1``;` `  ``// SubString of str from the``  ``// indices l to r.``  ``String temp = str.substring(l, r - l + ``1``);` `  ``// Extract kth Largest character``  ``char` `ans =``    ``find_kth_largest(temp.toCharArray(), k);` `  ``return` `ans;``}` `// Function to replace character at``// pos of str by the character s``static` `void` `updateString(``char` `[]str,``                         ``int` `pos, ``char` `s)``{``  ``// Index of S to be updated.``  ``int` `index = pos - ``1``;``  ``char` `c = s;` `  ``// Character to be replaced``  ``// at index in S``  ``str[index] = c;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``  ``// Given String``  ``String str = ``"abcddef"``;` `  ``// Count of queries``  ``int` `Q = ``3``;` `  ``// Queries``  ``System.out.print(printCharacter(str, ``1``,``                                  ``2``, ``2``) + ``"\n"``);``  ``updateString(str.toCharArray(), ``4``, ``'g'``);``  ``System.out.print(printCharacter(str, ``1``,``                                  ``5``, ``4``) + ``"\n"``);``}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python3 Program to implement``# the above approach``# Function to find the kth greatest``# character from the strrijng``def` `find_kth_largest(strr, k):` `    ``# Sorting the in``    ``# non-increasing Order``    ``strr ``=` `sorted``(strr)``    ``strr ``=` `strr[:: ``-``1``]``    ``return` `strr[k ``-` `1``]` `# Function to prthe K-th character``# from the subS[l] .. S[r]``def` `printCharacter(strr, l, r, k):``  ` `    ``#0-based indexing``    ``l ``=` `l ``-` `1``    ``r ``=` `r ``-` `1` `    ``# Subof strr from the``    ``# indices l to r.``    ``temp``=` `strr[l: r ``-` `l ``+` `1``]` `    ``#Extract kth Largest character``    ``ans ``=` `find_kth_largest(temp, k)` `    ``return` `ans` `# Function to replace character at``# pos of strr by the character s``def` `updateString(strr, pos, s):``    ``# Index of S to be updated.``    ``index ``=` `pos ``-` `1``    ``c ``=` `s` `    ``# Character to be replaced``    ``# at index in S``    ``strr[index] ``=` `c` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``  ` `    ``# Given strring``    ``strr ``=` `"abcddef"``    ``strr``=``[i ``for` `i ``in` `strr]` `    ``# Count of queries``    ``Q ``=` `3` `    ``# Queries``    ``print``(printCharacter(strr, ``1``, ``2``, ``2``))``    ``updateString(strr, ``4``, ``'g'``)``    ``print``(printCharacter(strr, ``1``, ``5``, ``4``))` `# This code is contributed by Mohit Kumar 29`

## C#

 `// C# program to implement``// the above approach``using` `System;` `class` `GFG{` `// Function to find the kth greatest``// character from the strijng``static` `char` `find_kth_largest(``char` `[]str,``                             ``int` `k)``{``    ` `    ``// Sorting the String in``    ``// non-increasing Order``    ``Array.Sort(str);``    ``reverse(str);``    ` `    ``return` `str[k - 1];``}` `static` `char``[] reverse(``char` `[]a)``{``    ``int` `i, n = a.Length;``    ``char` `t;``    ` `    ``for``(i = 0; i < n / 2; i++)``    ``{``        ``t = a[i];``        ``a[i] = a[n - i - 1];``        ``a[n - i - 1] = t;``    ``}``    ``return` `a;``}` `// Function to print the K-th character``// from the subString S[l] .. S[r]``static` `char` `printchar(String str, ``int` `l,``                           ``int` `r, ``int` `k)``{``    ` `    ``// 0-based indexing``    ``l = l - 1;``    ``r = r - 1;` `    ``// SubString of str from the``    ``// indices l to r.``    ``String temp = str.Substring(l, r - l + 1);` `    ``// Extract kth Largest character``    ``char` `ans = find_kth_largest(``               ``temp.ToCharArray(), k);` `    ``return` `ans;``}` `// Function to replace character at``// pos of str by the character s``static` `void` `updateString(``char` `[]str,``                         ``int` `pos, ``char` `s)``{``    ` `    ``// Index of S to be updated.``    ``int` `index = pos - 1;``    ``char` `c = s;` `    ``// char to be replaced``    ``// at index in S``    ``str[index] = c;``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``    ` `    ``// Given String``    ``String str = ``"abcddef"``;` `    ``// Count of queries``    ``//int Q = 3;` `    ``// Queries``    ``Console.Write(printchar(str, 1, 2, 2) + ``"\n"``);``    ``updateString(str.ToCharArray(), 4, ``'g'``);``    ` `    ``Console.Write(printchar(str, 1, 5, 4) + ``"\n"``);``}``}` `// This code is contributed by Amit Katiyar`
Output:
```a
b

```

Efficient Approach: The above approach can be optimized by precomputing the count of all the characters which are greater than or equal to character C ( ‘a’ ≤ C ≤ ‘z’ ) efficiently using a Fenwick Tree.
Follow the steps below to solve the problem:

• Create a Fenwick Tree to store the frequencies of all characters from ‘a’ to ‘z
• For every query of type 1, check for each character from ‘z’ to ‘a’, whether it is the Kth the greatest character.
• In order to perform this, traverse from ‘z’ to ‘a’ and for each character, check if the count of all the characters traversed becomes ≥ K or not. Print the character for which the count becomes ≥ K.

Below is the implementation of the above approach:

## C++

 `// C++ Program to implement``// the above approach` `#include "bits/stdc++.h"``using` `namespace` `std;` `// Maximum Size of a String``const` `int` `maxn = 100005;` `// Fenwick Tree to store the``// frequencies of 26 alphabets``int` `BITree[maxn];` `// Size of the String.``int` `N;` `// Function to update Fenwick Tree for``// Character c at index val``void` `update_BITree(``int` `index, ``char` `C,``                   ``int` `val)``{``    ``while` `(index <= N) {` `        ``// Add val to current node``        ``// Fenwick Tree``        ``BITree[C - ``'a'``][index]``            ``+= val;` `        ``// Move index to parent node``        ``// in update View``        ``index += (index & -index);``    ``}``}` `// Function to get sum of frequencies``// of character c till index``int` `sum_BITree(``int` `index, ``char` `C)``{` `    ``// Stores the sum``    ``int` `s = 0;``    ``while` `(index) {` `        ``// Add current element of``        ``// Fenwick tree to sum``        ``s += BITree[C - ``'a'``][index];` `        ``// Move index to parent node``        ``// in getSum View``        ``index -= (index & -index);``    ``}``    ``return` `s;``}` `// Function to create the Fenwick tree``void` `buildTree(string str)``{``    ``for` `(``int` `i = 1; i <= N; i++) {` `        ``update_BITree(i, str[i], 1);``    ``}``    ``cout << endl;``}` `// Function to print the kth largest``// character in the range of l to r``char` `printCharacter(string str, ``int` `l,``                    ``int` `r, ``int` `k)``{` `    ``// Stores the count of``    ``// charcters``    ``int` `count = 0;` `    ``// Stores the required``    ``// character``    ``char` `ans;` `    ``for` `(``char` `C = ``'z'``; C >= ``'a'``; C--) {` `        ``// Calculate frequency of``        ``// C in the given range``        ``int` `times = sum_BITree(r, C)``                    ``- sum_BITree(l - 1, C);` `        ``// Increase count``        ``count += times;` `        ``// If count exceeds K``        ``if` `(count >= k) {` `            ``// Required character``            ``// found``            ``ans = C;``            ``break``;``        ``}``    ``}` `    ``return` `ans;``}` `// Function to update character``// at pos by character s``void` `updateTree(string str, ``int` `pos,``                ``char` `s)``{` `    ``// 0 based index system``    ``int` `index = pos;``    ``update_BITree(index, str[index], -1);` `    ``str[index] = s;``    ``update_BITree(index, s, 1);``}` `// Driver Code``int` `main()``{``    ``string str = ``"abcddef"``;``    ``N = str.size();` `    ``// Makes the string 1-based indexed``    ``str = ``'#'` `+ str;` `    ``// Number of queries``    ``int` `Q = 3;` `    ``// Construct the Fenwick Tree``    ``buildTree(str);` `    ``cout << printCharacter(str, 1, 2, 2)``         ``<< endl;``    ``updateTree(str, 4, ``'g'``);``    ``cout << printCharacter(str, 1, 5, 4)``         ``<< endl;` `    ``return` `0;``}`

## Java

 `// Java Program to implement``// the above approach` `//include "bits/stdJava.h"``import` `java.util.*;``class` `GFG{` `// Maximum Size of a String``static` `int` `maxn = ``100005``;` `// Fenwick Tree to store the``// frequencies of 26 alphabets``static` `int` `[][]BITree = ``new` `int``[``26``][maxn];` `// Size of the String.``static` `int` `N;` `// Function to update Fenwick Tree for``// Character c at index val``static` `void` `update_BITree(``int` `index,``                          ``char` `C, ``int` `val)``{``  ``while` `(index <= N)``  ``{``    ``// Add val to current node``    ``// Fenwick Tree``    ``BITree[C - ``'a'``][index] += val;` `    ``// Move index to parent node``    ``// in update View``    ``index += (index & -index);``  ``}``}` `// Function to get sum of frequencies``// of character c till index``static` `int` `sum_BITree(``int` `index, ``char` `C)``{` `  ``// Stores the sum``  ``int` `s = ``0``;``  ``while` `(index > ``0``)``  ``{``    ``// Add current element of``    ``// Fenwick tree to sum``    ``s += BITree[C - ``'a'``][index];` `    ``// Move index to parent node``    ``// in getSum View``    ``index -= (index & -index);``  ``}``  ``return` `s;``}` `// Function to create the Fenwick tree``static` `void` `buildTree(String str)``{``  ``for` `(``int` `i = ``1``; i <= N; i++)``  ``{``    ``update_BITree(i, str.charAt(i), ``1``);``  ``}``  ``System.out.println();``}` `// Function to print the kth largest``// character in the range of l to r``static` `char` `printCharacter(String str, ``int` `l,``                           ``int` `r, ``int` `k)``{``  ``// Stores the count of``  ``// charcters``  ``int` `count = ``0``;` `  ``// Stores the required``  ``// character``  ``char` `ans = ``0``;` `  ``for` `(``char` `C = ``'z'``; C >= ``'a'``; C--)``  ``{``    ``// Calculate frequency of``    ``// C in the given range``    ``int` `times = sum_BITree(r, C) -``      ``sum_BITree(l - ``1``, C);` `    ``// Increase count``    ``count += times;` `    ``// If count exceeds K``    ``if` `(count >= k)``    ``{``      ``// Required character``      ``// found``      ``ans = C;``      ``break``;``    ``}``  ``}``  ``return` `ans;``}` `// Function to update character``// at pos by character s``static` `void` `updateTree(String str,``                       ``int` `pos, ``char` `s)``{``    ``// 0 based index system``    ``int` `index = pos;``    ``update_BITree(index,``                  ``str.charAt(index), -``1``);``    ``str = str.substring(``0``, index) + s +``          ``str.substring(index + ``1``);``    ``update_BITree(index, s, ``1``);``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``  ``String str = ``"abcddef"``;``  ``N = str.length();` `  ``// Makes the String 1-based indexed``  ``str = ``'/'` `+ str;` `  ``// Number of queries``  ``int` `Q = ``3``;` `  ``// Conthe Fenwick Tree``  ``buildTree(str);` `  ``System.out.print(printCharacter(str, ``1``,``                                  ``2``, ``2``) + ``"\n"``);``  ``updateTree(str, ``4``, ``'g'``);``  ``System.out.print(printCharacter(str, ``1``,``                                  ``5``, ``4``) + ``"\n"``);` `}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python3 Program to implement``# the above approach` `# Maximum Size of a String``maxn ``=` `100005` `# Fenwick Tree to store the``# frequencies of 26 alphabets``BITree ``=` `[[``0` `for` `x ``in` `range``(maxn)]``             ``for` `y ``in` `range``(``26``)]` `# Size of the String.``N ``=` `0` `# Function to update Fenwick Tree for``# Character c at index val``def` `update_BITree(index, C, val):` `    ``while` `(index <``=` `N):` `        ``# Add val to current node``        ``# Fenwick Tree``        ``BITree[``ord``(C) ``-``               ``ord``(``'a'``)][index]``+``=` `val` `        ``# Move index to parent node``        ``# in update View``        ``index ``+``=` `(index & ``-``index)` `# Function to get sum of``# frequencies of character``# c till index``def` `sum_BITree(index, C):` `    ``# Stores the sum``    ``s ``=` `0``    ``while` `(index):` `        ``# Add current element of``        ``# Fenwick tree to sum``        ``s ``+``=` `BITree[``ord``(C) ``-``                    ``ord``(``'a'``)][index]` `        ``# Move index to parent node``        ``# in getSum View``        ``index ``-``=` `(index & ``-``index)``    ``return` `s` `# Function to create``# the Fenwick tree``def` `buildTree(st):``  ` `    ``for` `i ``in` `range``(``1``,``                   ``N ``+` `1``):``        ``update_BITree(i,``                      ``st[i], ``1``)``    ` `    ``print``()` `# Function to print the``# kth largest character``# in the range of l to r``def` `printCharacter(st, l,``                   ``r, k):``  ` `    ``# Stores the count of``    ``# charcters``    ``count ``=` `0` `    ``for` `C ``in` `range``(``ord``(``'z'``),``                   ``ord``(``'a'``) ``-``                   ``1``, ``-``1``):` `        ``# Calculate frequency of``        ``# C in the given range``        ``times ``=` `(sum_BITree(r, ``chr``(C)) ``-``                 ``sum_BITree(l ``-` `1``, ``chr``(C)))` `        ``# Increase count``        ``count ``+``=` `times` `        ``# If count exceeds K``        ``if` `(count >``=` `k):` `            ``# Required character``            ``# found``            ``ans ``=` `chr``( C)``            ``break``   ` `    ``return` `ans` `# Function to update character``# at pos by character s``def` `updateTree(st, pos, s):``  ` `    ``# 0 based index system``    ``index ``=` `pos;``    ``update_BITree(index,``                  ``st[index], ``-``1``)` `    ``st.replace(st[index], s, ``1``)``    ``update_BITree(index, s, ``1``)` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``  ` `    ``st ``=` `"abcddef"``    ``N ``=` `len``(st)` `    ``# Makes the string``    ``# 1-based indexed``    ``st ``=` `'#'` `+` `st` `    ``# Number of queries``    ``Q ``=` `3` `    ``# Construct the Fenwick Tree``    ``buildTree(st)` `    ``print` `(printCharacter(st, ``1``,``                          ``2``, ``2``))``    ``updateTree(st, ``4``, ``'g'``)``    ``print` `(printCharacter(st, ``1``,``                          ``5``, ``4``))` `# This code is contributed by Chitranayal`

## C#

 `// C# Program to implement``// the above approach``using` `System;``class` `GFG{` `// Maximum Size of a String``static` `int` `maxn = 100005;` `// Fenwick Tree to store the``// frequencies of 26 alphabets``static` `int` `[,]BITree = ``new` `int``[26, maxn];` `// Size of the String.``static` `int` `N;` `// Function to update Fenwick Tree for``// char c at index val``static` `void` `update_BITree(``int` `index,``                          ``char` `C, ``int` `val)``{``  ``while` `(index <= N)``  ``{``    ``// Add val to current node``    ``// Fenwick Tree``    ``BITree[C - ``'a'``, index] += val;` `    ``// Move index to parent node``    ``// in update View``    ``index += (index & -index);``  ``}``}` `// Function to get sum of frequencies``// of character c till index``static` `int` `sum_BITree(``int` `index, ``char` `C)``{``  ``// Stores the sum``  ``int` `s = 0;``  ``while` `(index > 0)``  ``{``    ``// Add current element of``    ``// Fenwick tree to sum``    ``s += BITree[C - ``'a'``, index];` `    ``// Move index to parent node``    ``// in getSum View``    ``index -= (index & -index);``  ``}``  ``return` `s;``}` `// Function to create the Fenwick tree``static` `void` `buildTree(String str)``{``  ``for` `(``int` `i = 1; i <= N; i++)``  ``{``    ``update_BITree(i, str[i], 1);``  ``}``  ``Console.WriteLine();``}` `// Function to print the kth largest``// character in the range of l to r``static` `char` `printchar(String str, ``int` `l,``                      ``int` `r, ``int` `k)``{``  ``// Stores the count of``  ``// charcters``  ``int` `count = 0;` `  ``// Stores the required``  ``// character``  ``char` `ans = (``char``)0;` `  ``for` `(``char` `C = ``'z'``; C >= ``'a'``; C--)``  ``{``    ``// Calculate frequency of``    ``// C in the given range``    ``int` `times = sum_BITree(r, C) -``                ``sum_BITree(l - 1, C);` `    ``// Increase count``    ``count += times;` `    ``// If count exceeds K``    ``if` `(count >= k)``    ``{``      ``// Required character``      ``// found``      ``ans = C;``      ``break``;``    ``}``  ``}``  ``return` `ans;``}` `// Function to update character``// at pos by character s``static` `void` `updateTree(String str,``                       ``int` `pos, ``char` `s)``{``  ``// 0 based index system``  ``int` `index = pos;``  ``update_BITree(index,``                ``str[index], -1);``  ``str = str.Substring(0, index) + s +``    ``str.Substring(index + 1);``  ``update_BITree(index, s, 1);``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``  ``String str = ``"abcddef"``;``  ``N = str.Length;` `  ``// Makes the String 1-based indexed``  ``str = ``'/'` `+ str;` `  ``// Number of queries``  ``int` `Q = 3;` `  ``// Conthe Fenwick Tree``  ``buildTree(str);` `  ``Console.Write(printchar(str, 1, 2, 2) + ``"\n"``);``  ``updateTree(str, 4, ``'g'``);``  ``Console.Write(printchar(str, 1, 5, 4) + ``"\n"``);``}``}` `// This code is contributed by Rajput-Ji`
Output:
```a
b

```

Time Complexity: O( QlogN + NlogN )
Auxiliary Space: O(26 * maxn), where maxn denotes the maximum possible length of the string.

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live and Geeks Classes Live USA

My Personal Notes arrow_drop_up