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

22 Nov, 2021
Given a string str of length N, and Q queries of the following two types:
(1 L R K): Find the Kth greatest character (non-distinct) from the range of indices [L, R] (1-based indexing)(2 J C): Replace the Jth character from the string by character C.
(1 L R K): Find the Kth greatest character (non-distinct) from the range of indices [L, R] (1-based indexing)
(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:cb 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[4] 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:chd
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++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach #include "bits/stdc++.h"using namespace std; // Function to find the kth greatest// character from the strijngchar 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 svoid 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 Codeint 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 Program to implement// the above approach//include "bits/stdJava.h"import java.util.*;class GFG{ // Function to find the kth greatest// character from the strijngstatic 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 sstatic 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 Codepublic 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 Program to implement# the above approach# Function to find the kth greatest# character from the stringdef 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 sdef 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 Codeif __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# program to implement// the above approachusing System; class GFG{ // Function to find the kth greatest// character from the stringstatic 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 sstatic 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 Codepublic 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
<script>// Javascript Program to implement// the above approach//include "bits/stdJava.h" // Function to find the kth greatest// character from the strijngfunction find_kth_largest(str,k){  // Sorting the String in  // non-increasing Order  str.sort();  reverse(str);  return str[k - 1];} function reverse(a){    let i, n = a.length;    let t;    for (i = 0; i < Math.floor(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]function printCharacter(str,l,r,k){  // 0-based indexing  l = l - 1;  r = r - 1;    // SubString of str from the  // indices l to r.  let temp = str.substring(l, r - l + 1);    // Extract kth Largest character  let ans =    find_kth_largest(temp.split(""), k);    return ans;} // Function to replace character at// pos of str by the character sfunction updateString(str,pos,s){  // Index of S to be updated.  let index = pos - 1;  let c = s;    // Character to be replaced  // at index in S  str[index] = c;} // Driver Code// Given Stringlet str = "abcddef";// Count of querieslet Q = 3; // Queriesdocument.write(printCharacter(str, 1,                                2, 2) + "<br>");updateString(str.split(""), 4, 'g');document.write(printCharacter(str, 1,                                5, 4) + "<br>");   // This code is contributed by avanitrachhadiya2155</script>
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++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach #include "bits/stdc++.h"using namespace std; // Maximum Size of a Stringconst int maxn = 100005; // Fenwick Tree to store the// frequencies of 26 alphabetsint BITree[26][maxn]; // Size of the String.int N; // Function to update Fenwick Tree for// Character c at index valvoid 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 indexint 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 treevoid 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 rchar 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 svoid 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 Codeint 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 Program to implement// the above approach //include "bits/stdJava.h"import java.util.*;class GFG{ // Maximum Size of a Stringstatic int maxn = 100005; // Fenwick Tree to store the// frequencies of 26 alphabetsstatic int [][]BITree = new int[26][maxn]; // Size of the String.static int N; // Function to update Fenwick Tree for// Character c at index valstatic 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 indexstatic 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 treestatic 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 rstatic 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 sstatic 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 Codepublic 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 Program to implement# the above approach # Maximum Size of a Stringmaxn = 100005 # Fenwick Tree to store the# frequencies of 26 alphabetsBITree = [[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 valdef 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 indexdef 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 treedef 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 rdef 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 sdef 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 Codeif __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# Program to implement// the above approachusing System;class GFG{ // Maximum Size of a Stringstatic int maxn = 100005; // Fenwick Tree to store the// frequencies of 26 alphabetsstatic int [,]BITree = new int[26, maxn]; // Size of the String.static int N; // Function to update Fenwick Tree for// char c at index valstatic 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 indexstatic 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 treestatic 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 rstatic 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 sstatic 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 Codepublic 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
<script>// Javascript Program to implement// the above approach    // Maximum Size of a Stringlet maxn = 100005; // Fenwick Tree to store the// frequencies of 26 alphabetslet BITree = new Array(26);for(let i=0;i<26;i++){    BITree[i]=new Array(maxn);    for(let j=0;j<maxn;j++)    {        BITree[i][j]=0;    }     } // Size of the String.let N; // Function to update Fenwick Tree for// Character c at index valfunction update_BITree(index,C,val){    while (index <= N)  {    // Add val to current node    // Fenwick Tree    BITree[C.charCodeAt(0) - 'a'.charCodeAt(0)][index] += val;      // Move index to parent node    // in update View    index += (index & -index);  }} // Function to get sum of frequencies// of character c till indexfunction sum_BITree(index,C){    // Stores the sum  let s = 0;  while (index > 0)  {    // Add current element of    // Fenwick tree to sum    s += BITree[C.charCodeAt(0) - 'a'.charCodeAt(0)][index];      // Move index to parent node    // in getSum View    index -= (index & -index);  }  return s;} // Function to create the Fenwick treefunction buildTree(str){    for (let i = 1; i <= N; i++)  {    update_BITree(i, str[i], 1);  }  document.write("<br>");} // Function to print the kth largest// character in the range of l to rfunction printCharacter(str,l,r,k){    // Stores the count of  // characters  let count = 0;    // Stores the required  // character  let ans = 0;    for (let C = 'z'.charCodeAt(0); C >= 'a'.charCodeAt(0); C--)  {    // Calculate frequency of    // C in the given range    let times = sum_BITree(r, String.fromCharCode(C)) -      sum_BITree(l - 1, String.fromCharCode(C));      // Increase count    count += times;      // If count exceeds K    if (count >= k)    {      // Required character      // found      ans = String.fromCharCode(C);      break;    }  }  return ans;} // Function to update character// at pos by character sfunction updateTree(str,pos,s){    // 0 based index system    let index = pos;    update_BITree(index,                  str[index], -1);    str = str.substring(0, index) + s +          str.substring(index + 1);    update_BITree(index, s, 1);} // Driver Codelet str = "abcddef";N = str.length; // Makes the String 1-based indexedstr = '/' + str; // Number of querieslet Q = 3; // Construct the Fenwick TreebuildTree(str); document.write(printCharacter(str, 1,                                2, 2) + "<br>");updateTree(str, 4, 'g');document.write(printCharacter(str, 1,                                5, 4) + "<br>");  // This code is contributed by rag2127</script>
a
b
Time Complexity: O( QlogN + NlogN ) Auxiliary Space: O(26 * maxn), where maxn denotes the maximum possible length of the string.
mohit kumar 29
shikhasingrajput
amit143katiyar
Rajput-Ji
ukasp
sumitgumber28
akshaysingh98088
avanitrachhadiya2155
rag2127
sagartomar9927
ankita_saini
array-range-queries
BIT
frequency-counting
Advanced Data Structure
Arrays
Mathematical
Searching
Sorting
Strings
Arrays
Searching
Strings
Mathematical
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Decision Tree Introduction with example
Ordered Set and GNU C++ PBDS
Red-Black Tree | Set 2 (Insert)
Disjoint Set Data Structures
Binary Indexed Tree or Fenwick Tree
Arrays in Java
Arrays in C/C++
Maximum and minimum of an array using minimum number of comparisons
Write a program to reverse an array or string
Program for array rotation