 Open in App
Not now

# Queries to find Kth greatest character in a range [L, R] from a string with updates

• Last Updated : 22 Nov, 2021

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 string` `def` `find_kth_largest(strr, k):`   `    ``# Sorting the in` `    ``# non-increasing Order` `    ``strr ``=` `sorted``(strr)` `    ``strr ``=` `strr[:: ``-``1``]` `    ``return` `strr[k ``-` `1``]`   `# Function to print the 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 string` `    ``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 string` `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`

## Javascript

 ``

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` `    ``// characters` `    ``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` `  ``// characters` `  ``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``;`   `  ``// Construct the 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` `    ``# characters` `    ``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` `  ``// characters` `  ``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;`   `  ``// Construct the 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`

## Javascript

 ``

Output:

```a
b```

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

My Personal Notes arrow_drop_up
Related Articles