Queries to find kth greatest character in a range with updates (Easy Task)
Last Updated :
05 Feb, 2024
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.
Examples:
Input: str = “abcddef”, Q = 3, queries[][] = {{1, 2, 5, 3}, {2, 4, g}, {1, 1, 4, 3}}
Output:
c
b
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:
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.
C++
#include <bits/stdc++.h>
#include <algorithm>
#include <string>
using namespace std;
char printCharacter(string &str, int L, int R, int K) {
string substr = str.substr(L - 1, R - L + 1);
sort(substr.begin(), substr.end(), greater< char >());
return substr[K - 1];
}
void updateString(string &str, int J, char C) {
str[J - 1] = C;
}
int main() {
string str = "abcddef" ;
int Q = 3;
cout << printCharacter(str, 1, 2, 2)
<< endl;
updateString(str, 4, 'g' );
cout << printCharacter(str, 1, 5, 4)
<< endl;
return 0;
}
|
Java
import java.util.*;
public class GFG {
public static char printCharacter(String str, int L,
int R, int K)
{
String substr = str.substring(L - 1 , R);
char [] charArr = substr.toCharArray();
Arrays.sort(charArr);
String sortedStr = new String(charArr);
String revStr = new StringBuilder(sortedStr)
.reverse()
.toString();
return revStr.charAt(K - 1 );
}
public static void updateString(StringBuilder str,
int J, char C)
{
str.setCharAt(J - 1 , C);
}
public static void main(String[] args)
{
String str = "abcddef" ;
int Q = 3 ;
System.out.println(printCharacter(str, 1 , 2 , 2 ));
StringBuilder sb = new StringBuilder(str);
updateString(sb, 4 , 'g' );
str = sb.toString();
System.out.println(printCharacter(str, 1 , 5 , 4 ));
}
}
|
Python3
def printCharacter(string, L, R, K):
substr = string[L - 1 :R]
substr = sorted (substr, reverse = True )
return substr[K - 1 ]
def updateString(string, J, C):
string = string[:J - 1 ] + C + string[J:]
if __name__ = = '__main__' :
string = "abcddef"
Q = 3
print (printCharacter(string, 1 , 2 , 2 ))
updateString(string, 4 , 'g' )
print (printCharacter(string, 1 , 5 , 4 ))
|
C#
using System;
class Program {
static char PrintCharacter( string str, int L, int R,
int K)
{
string substr = str.Substring(L - 1, R - L + 1);
char [] chars = substr.ToCharArray();
Array.Sort(chars);
Array.Reverse(chars);
return chars[K - 1];
}
static string UpdateString( string str, int J, char C)
{
char [] chars = str.ToCharArray();
chars[J - 1] = C;
return new string (chars);
}
static void Main( string [] args)
{
string str = "abcddef" ;
int Q = 3;
Console.WriteLine(PrintCharacter(str, 1, 2, 2));
str = UpdateString(str, 4, 'g' );
Console.WriteLine(PrintCharacter(str, 1, 5, 4));
}
}
|
Javascript
function printCharacter(str, L, R, K) {
let substr = str.substring(L - 1, R);
substr = substr.split( '' ).sort( function (a, b) {
return b.localeCompare(a);
}).join( '' );
return substr.charAt(K - 1);
}
function updateString(str, J, C) {
str = str.substring(0, J - 1) + C + str.substring(J);
return str;
}
let str = "abcddef" ;
let Q = 3;
console.log(printCharacter(str, 1, 2, 2));
str = updateString(str, 4, 'g' );
console.log(printCharacter(str, 1, 5, 4));
|
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++
#include "bits/stdc++.h"
using namespace std;
char find_kth_largest(string str, int k)
{
sort(str.begin(), str.end(),
greater< char >());
return str[k - 1];
}
char printCharacter(string str, int l,
int r, int k)
{
l = l - 1;
r = r - 1;
string temp
= str.substr(l, r - l + 1);
char ans
= find_kth_largest(temp, k);
return ans;
}
void updateString(string str, int pos,
char s)
{
int index = pos - 1;
char c = s;
str[index] = c;
}
int main()
{
string str = "abcddef" ;
int Q = 3;
cout << printCharacter(str, 1, 2, 2)
<< endl;
updateString(str, 4, 'g' );
cout << printCharacter(str, 1, 5, 4)
<< endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static char find_kth_largest( char []str,
int k)
{
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;
}
static char printCharacter(String str, int l,
int r, int k)
{
l = l - 1 ;
r = r - 1 ;
String temp = str.substring(l, r - l + 1 );
char ans =
find_kth_largest(temp.toCharArray(), k);
return ans;
}
static void updateString( char []str,
int pos, char s)
{
int index = pos - 1 ;
char c = s;
str[index] = c;
}
public static void main(String[] args)
{
String str = "abcddef" ;
int Q = 3 ;
System.out.print(printCharacter(str, 1 ,
2 , 2 ) + "\n" );
updateString(str.toCharArray(), 4 , 'g' );
System.out.print(printCharacter(str, 1 ,
5 , 4 ) + "\n" );
}
}
|
Python3
def find_kth_largest(strr, k):
strr = sorted (strr)
strr = strr[:: - 1 ]
return strr[k - 1 ]
def printCharacter(strr, l, r, k):
l = l - 1
r = r - 1
temp = strr[l: r - l + 1 ]
ans = find_kth_largest(temp, k)
return ans
def updateString(strr, pos, s):
index = pos - 1
c = s
strr[index] = c
if __name__ = = '__main__' :
strr = "abcddef"
strr = [i for i in strr]
Q = 3
print (printCharacter(strr, 1 , 2 , 2 ))
updateString(strr, 4 , 'g' )
print (printCharacter(strr, 1 , 5 , 4 ))
|
C#
using System;
class GFG{
static char find_kth_largest( char []str,
int k)
{
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;
}
static char printchar(String str, int l,
int r, int k)
{
l = l - 1;
r = r - 1;
String temp = str.Substring(l, r - l + 1);
char ans = find_kth_largest(
temp.ToCharArray(), k);
return ans;
}
static void updateString( char []str,
int pos, char s)
{
int index = pos - 1;
char c = s;
str[index] = c;
}
public static void Main(String[] args)
{
String str = "abcddef" ;
Console.Write(printchar(str, 1, 2, 2) + "\n" );
updateString(str.ToCharArray(), 4, 'g' );
Console.Write(printchar(str, 1, 5, 4) + "\n" );
}
}
|
Javascript
<script>
function find_kth_largest(str,k)
{
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 printCharacter(str,l,r,k)
{
l = l - 1;
r = r - 1;
let temp = str.substring(l, r - l + 1);
let ans =
find_kth_largest(temp.split( "" ), k);
return ans;
}
function updateString(str,pos,s)
{
let index = pos - 1;
let c = s;
str[index] = c;
}
let str = "abcddef" ;
let Q = 3;
document.write(printCharacter(str, 1,
2, 2) + "<br>" );
updateString(str.split( "" ), 4, 'g' );
document.write(printCharacter(str, 1,
5, 4) + "<br>" );
</script>
|
Time Complexity: O(Q(r – l + 1) log (r – l + 1)) + O(Q), where Q is the number of queries, and r and l are the endpoints of the substring in each query.
Space Complexity: O(1)
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++
#include "bits/stdc++.h"
using namespace std;
const int maxn = 100005;
int BITree[26][maxn];
int N;
void update_BITree( int index, char C,
int val)
{
while (index <= N) {
BITree[C - 'a' ][index]
+= val;
index += (index & -index);
}
}
int sum_BITree( int index, char C)
{
int s = 0;
while (index) {
s += BITree[C - 'a' ][index];
index -= (index & -index);
}
return s;
}
void buildTree(string str)
{
for ( int i = 1; i <= N; i++) {
update_BITree(i, str[i], 1);
}
cout << endl;
}
char printCharacter(string str, int l,
int r, int k)
{
int count = 0;
char ans;
for ( char C = 'z' ; C >= 'a' ; C--) {
int times = sum_BITree(r, C)
- sum_BITree(l - 1, C);
count += times;
if (count >= k) {
ans = C;
break ;
}
}
return ans;
}
void updateTree(string str, int pos,
char s)
{
int index = pos;
update_BITree(index, str[index], -1);
str[index] = s;
update_BITree(index, s, 1);
}
int main()
{
string str = "abcddef" ;
N = str.size();
str = '#' + str;
int Q = 3;
buildTree(str);
cout << printCharacter(str, 1, 2, 2)
<< endl;
updateTree(str, 4, 'g' );
cout << printCharacter(str, 1, 5, 4)
<< endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int maxn = 100005 ;
static int [][]BITree = new int [ 26 ][maxn];
static int N;
static void update_BITree( int index,
char C, int val)
{
while (index <= N)
{
BITree[C - 'a' ][index] += val;
index += (index & -index);
}
}
static int sum_BITree( int index, char C)
{
int s = 0 ;
while (index > 0 )
{
s += BITree[C - 'a' ][index];
index -= (index & -index);
}
return s;
}
static void buildTree(String str)
{
for ( int i = 1 ; i <= N; i++)
{
update_BITree(i, str.charAt(i), 1 );
}
System.out.println();
}
static char printCharacter(String str, int l,
int r, int k)
{
int count = 0 ;
char ans = 0 ;
for ( char C = 'z' ; C >= 'a' ; C--)
{
int times = sum_BITree(r, C) -
sum_BITree(l - 1 , C);
count += times;
if (count >= k)
{
ans = C;
break ;
}
}
return ans;
}
static void updateTree(String str,
int pos, char s)
{
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 );
}
public static void main(String[] args)
{
String str = "abcddef" ;
N = str.length();
str = '/' + str;
int Q = 3 ;
buildTree(str);
System.out.print(printCharacter(str, 1 ,
2 , 2 ) + "\n" );
updateTree(str, 4 , 'g' );
System.out.print(printCharacter(str, 1 ,
5 , 4 ) + "\n" );
}
}
|
Python3
maxn = 100005
BITree = [[ 0 for x in range (maxn)]
for y in range ( 26 )]
N = 0
def update_BITree(index, C, val):
while (index < = N):
BITree[ ord (C) -
ord ( 'a' )][index] + = val
index + = (index & - index)
def sum_BITree(index, C):
s = 0
while (index):
s + = BITree[ ord (C) -
ord ( 'a' )][index]
index - = (index & - index)
return s
def buildTree(st):
for i in range ( 1 ,
N + 1 ):
update_BITree(i,
st[i], 1 )
print ()
def printCharacter(st, l,
r, k):
count = 0
for C in range ( ord ( 'z' ),
ord ( 'a' ) -
1 , - 1 ):
times = (sum_BITree(r, chr (C)) -
sum_BITree(l - 1 , chr (C)))
count + = times
if (count > = k):
ans = chr ( C)
break
return ans
def updateTree(st, pos, s):
index = pos;
update_BITree(index,
st[index], - 1 )
st.replace(st[index], s, 1 )
update_BITree(index, s, 1 )
if __name__ = = "__main__" :
st = "abcddef"
N = len (st)
st = '#' + st
Q = 3
buildTree(st)
print (printCharacter(st, 1 ,
2 , 2 ))
updateTree(st, 4 , 'g' )
print (printCharacter(st, 1 ,
5 , 4 ))
|
C#
using System;
class GFG{
static int maxn = 100005;
static int [,]BITree = new int [26, maxn];
static int N;
static void update_BITree( int index,
char C, int val)
{
while (index <= N)
{
BITree[C - 'a' , index] += val;
index += (index & -index);
}
}
static int sum_BITree( int index, char C)
{
int s = 0;
while (index > 0)
{
s += BITree[C - 'a' , index];
index -= (index & -index);
}
return s;
}
static void buildTree(String str)
{
for ( int i = 1; i <= N; i++)
{
update_BITree(i, str[i], 1);
}
Console.WriteLine();
}
static char printchar(String str, int l,
int r, int k)
{
int count = 0;
char ans = ( char )0;
for ( char C = 'z' ; C >= 'a' ; C--)
{
int times = sum_BITree(r, C) -
sum_BITree(l - 1, C);
count += times;
if (count >= k)
{
ans = C;
break ;
}
}
return ans;
}
static void updateTree(String str,
int pos, char s)
{
int index = pos;
update_BITree(index,
str[index], -1);
str = str.Substring(0, index) + s +
str.Substring(index + 1);
update_BITree(index, s, 1);
}
public static void Main(String[] args)
{
String str = "abcddef" ;
N = str.Length;
str = '/' + str;
int Q = 3;
buildTree(str);
Console.Write(printchar(str, 1, 2, 2) + "\n" );
updateTree(str, 4, 'g' );
Console.Write(printchar(str, 1, 5, 4) + "\n" );
}
}
|
Javascript
<script>
let maxn = 100005;
let 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;
}
}
let N;
function update_BITree(index,C,val)
{
while (index <= N)
{
BITree[C.charCodeAt(0) - 'a' .charCodeAt(0)][index] += val;
index += (index & -index);
}
}
function sum_BITree(index,C)
{
let s = 0;
while (index > 0)
{
s += BITree[C.charCodeAt(0) - 'a' .charCodeAt(0)][index];
index -= (index & -index);
}
return s;
}
function buildTree(str)
{
for (let i = 1; i <= N; i++)
{
update_BITree(i, str[i], 1);
}
document.write( "<br>" );
}
function printCharacter(str,l,r,k)
{
let count = 0;
let ans = 0;
for (let C = 'z' .charCodeAt(0); C >= 'a' .charCodeAt(0); C--)
{
let times = sum_BITree(r, String.fromCharCode(C)) -
sum_BITree(l - 1, String.fromCharCode(C));
count += times;
if (count >= k)
{
ans = String.fromCharCode(C);
break ;
}
}
return ans;
}
function updateTree(str,pos,s)
{
let index = pos;
update_BITree(index,
str[index], -1);
str = str.substring(0, index) + s +
str.substring(index + 1);
update_BITree(index, s, 1);
}
let str = "abcddef" ;
N = str.length;
str = '/' + str;
let Q = 3;
buildTree(str);
document.write(printCharacter(str, 1,
2, 2) + "<br>" );
updateTree(str, 4, 'g' );
document.write(printCharacter(str, 1,
5, 4) + "<br>" );
</script>
|
Time Complexity: O( QlogN + NlogN )
Auxiliary Space: O(26 * maxn), where maxn denotes the maximum possible length of the string.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...