Given a string str, the task is to answer Q queries where every query consists of two integers L and R and we have to find the last non-repeating character in the sub-string str[L…R]. If there is no non-repeating character then print -1.
Examples:
Input: str = “GeeksForGeeks”, q[] = {{2, 9}, {2, 3}, {0, 12}}
Output:
G
k
r
Sub-string for the queries are “eksForGe”, “ek” and “GeeksForGeeks” and their last non-repeating characters are ‘G’, ‘k’ and ‘r’ respectively.
‘G’ is the first character from the end in given range which has frequency 1.
Input: str = “xxyyxx”, q[] = {{2, 3}, {3, 4}}
Output:
-1
x
Approach: Create a frequency array freq[][] where freq[i][j] stores the frequency of the character in the sub-string str[0…j] whose ASCII value is i. Now, frequency of any character in the sub-string str[i…j] whose ASCII value is x can be calculated as freq[x][j] = freq[x][i – 1].
Now for every query, start traversing the string in the given range i.e. str[L…R] and for every character, if its frequency is 1 then this is the last non-repeating character in the required sub-string. If all the characters have frequency greater than 1 then print -1.
Below is the implementation of the above approach:
// C++ implementation of the approach #include<bits/stdc++.h> using namespace std;
// Maximum distinct characters possible int MAX = 256;
// To store the frequency of the characters int freq[256][1000] = {0};
// Function to pre-calculate the frequency array void preCalculate(string str, int n)
{ // Only the first character has
// frequency 1 till index 0
freq[( int )str[0]][0] = 1;
// Starting from the second
// character of the string
for ( int i = 1; i < n; i++)
{
char ch = str[i];
// For every possible character
for ( int j = 0; j < MAX; j++)
{
// Current character under consideration
char charToUpdate = ( char )j;
// If it is equal to the character
// at the current index
if (charToUpdate == ch)
freq[j][i] = freq[j][i - 1] + 1;
else
freq[j][i] = freq[j][i - 1];
}
}
} // Function to return the frequency of the // given character in the sub-string str[l...r] int getFrequency( char ch, int l, int r)
{ if (l == 0)
return freq[( int )ch][r];
else
return (freq[( int )ch][r] - freq[( int )ch][l - 1]);
} string getString( char x)
{ // string class has a constructor
// that allows us to specify size of
// string as first parameter and character
// to be filled in given size as second
// parameter.
string s(1, x);
return s;
} // Function to return the last non-repeating character string lastNonRepeating(string str, int n, int l, int r)
{ // Starting from the last character
for ( int i = r; i >= l; i--)
{
// Current character
char ch = str[i];
// If frequency of the current character is 1
// then return the character
if (getFrequency(ch, l, r) == 1)
return getString(ch);
}
// All the characters of the
// sub-string are repeating
return "-1" ;
} // Driver code int main()
{ string str = "GeeksForGeeks" ;
int n = str.length();
int queries[3][2] = { { 2, 9 }, { 2, 3 }, { 0, 12 } };
int q =3;
// Pre-calculate the frequency array
preCalculate(str, n);
for ( int i = 0; i < q; i++)
{
cout << (lastNonRepeating(str, n,
queries[i][0],
queries[i][1]))<<endl;;
}
} // This code is contributed by Arnab Kundu |
// Java implementation of the approach public class GFG {
// Maximum distinct characters possible
static final int MAX = 256 ;
// To store the frequency of the characters
static int freq[][];
// Function to pre-calculate the frequency array
static void preCalculate(String str, int n)
{
// Only the first character has
// frequency 1 till index 0
freq[( int )str.charAt( 0 )][ 0 ] = 1 ;
// Starting from the second
// character of the string
for ( int i = 1 ; i < n; i++) {
char ch = str.charAt(i);
// For every possible character
for ( int j = 0 ; j < MAX; j++) {
// Current character under consideration
char charToUpdate = ( char )j;
// If it is equal to the character
// at the current index
if (charToUpdate == ch)
freq[j][i] = freq[j][i - 1 ] + 1 ;
else
freq[j][i] = freq[j][i - 1 ];
}
}
}
// Function to return the frequency of the
// given character in the sub-string str[l...r]
static int getFrequency( char ch, int l, int r)
{
if (l == 0 )
return freq[( int )ch][r];
else
return (freq[( int )ch][r] - freq[( int )ch][l - 1 ]);
}
// Function to return the last non-repeating character
static String lastNonRepeating(String str, int n, int l, int r)
{
// Starting from the last character
for ( int i = r; i >= l; i--) {
// Current character
char ch = str.charAt(i);
// If frequency of the current character is 1
// then return the character
if (getFrequency(ch, l, r) == 1 )
return ( "" + ch);
}
// All the characters of the
// sub-string are repeating
return "-1" ;
}
// Driver code
public static void main(String[] args)
{
String str = "GeeksForGeeks" ;
int n = str.length();
int queries[][] = { { 2 , 9 }, { 2 , 3 }, { 0 , 12 } };
int q = queries.length;
// Pre-calculate the frequency array
freq = new int [MAX][n];
preCalculate(str, n);
for ( int i = 0 ; i < q; i++) {
System.out.println(lastNonRepeating(str, n,
queries[i][ 0 ],
queries[i][ 1 ]));
}
}
} |
# Python3 implementation of the approach # Maximum distinct characters possible MAX = 256
# To store the frequency of the characters freq = [[ 0 for i in range ( 256 )]
for j in range ( 1000 )]
# Function to pre-calculate # the frequency array def preCalculate(string, n):
# Only the first character has
# frequency 1 till index 0
freq[ ord (string[ 0 ])][ 0 ] = 1
# Starting from the second
# character of the string
for i in range ( 1 , n):
ch = string[i]
# For every possible character
for j in range ( MAX ):
# Current character under consideration
charToUpdate = chr (j)
# If it is equal to the character
# at the current index
if charToUpdate = = ch:
freq[j][i] = freq[j][i - 1 ] + 1
else :
freq[j][i] = freq[j][i - 1 ]
# Function to return the frequency of the # given character in the sub-string str[l...r] def getFrequency(ch, l, r):
if l = = 0 :
return freq[ ord (ch)][r]
else :
return (freq[ ord (ch)][r] -
freq[ ord (ch)][l - 1 ])
# Function to return the # last non-repeating character def lastNonRepeating(string, n, l, r):
# Starting from the last character
for i in range (r, l - 1 , - 1 ):
# Current character
ch = string[i]
# If frequency of the current character is 1
# then return the character
if getFrequency(ch, l, r) = = 1 :
return ch
# All the characters of the
# sub-string are repeating
return "-1"
# Driver Code if __name__ = = "__main__" :
string = "GeeksForGeeks"
n = len (string)
queries = [( 2 , 9 ), ( 2 , 3 ), ( 0 , 12 )]
q = len (queries)
# Pre-calculate the frequency array
preCalculate(string, n)
for i in range (q):
print (lastNonRepeating(string, n,
queries[i][ 0 ],
queries[i][ 1 ]))
# This code is contributed by # sanjeev2552 |
// C# implementation of the approach using System;
class GFG
{ // Maximum distinct characters possible
static int MAX = 256;
// To store the frequency of the characters
static int [,]freq;
// Function to pre-calculate the frequency array
static void preCalculate( string str, int n)
{
// Only the first character has
// frequency 1 till index 0
freq[( int )str[0],0] = 1;
// Starting from the second
// character of the string
for ( int i = 1; i < n; i++)
{
char ch = str[i];
// For every possible character
for ( int j = 0; j < MAX; j++)
{
// Current character under consideration
char charToUpdate = ( char )j;
// If it is equal to the character
// at the current index
if (charToUpdate == ch)
freq[j, i] = freq[j, i - 1] + 1;
else
freq[j, i] = freq[j, i - 1];
}
}
}
// Function to return the frequency of the
// given character in the sub-string str[l...r]
static int getFrequency( char ch, int l, int r)
{
if (l == 0)
return freq[( int )ch, r];
else
return (freq[( int )ch, r] - freq[( int )ch, l - 1]);
}
// Function to return the last non-repeating character
static String lastNonRepeating( string str, int n, int l, int r)
{
// Starting from the last character
for ( int i = r; i >= l; i--)
{
// Current character
char ch = str[i];
// If frequency of the current character is 1
// then return the character
if (getFrequency(ch, l, r) == 1)
return ( "" + ch);
}
// All the characters of the
// sub-string are repeating
return "-1" ;
}
// Driver code
public static void Main()
{
string str = "GeeksForGeeks" ;
int n = str.Length;
int [,]queries = { { 2, 9 }, { 2, 3 }, { 0, 12 } };
int q = queries.Length;
// Pre-calculate the frequency array
freq = new int [MAX,n];
preCalculate(str, n);
for ( int i = 0; i < q; i++)
{
Console.WriteLine(lastNonRepeating(str, n,
queries[i,0],
queries[i,1]));
}
}
} // This code is contributed by AnkitRai01 |
<?php // PHP implementation of the approach // Maximum distinct characters possible $MAX = 256;
// To store the frequency of the characters $freq = array_fill (0, 256, array_fill (0, 1000, 0));
// Function to pre-calculate the frequency array function preCalculate( $str , $n )
{ global $freq ;
global $MAX ;
// Only the first character has
// frequency 1 till index 0
$freq [ord( $str [0])][0] = 1;
// Starting from the second
// character of the string
for ( $i = 1; $i < $n ; $i ++)
{
$ch = $str [ $i ];
// For every possible character
for ( $j = 0; $j < $MAX ; $j ++)
{
// Current character under consideration
$charToUpdate = chr ( $j );
// If it is equal to the character
// at the current index
if ( $charToUpdate == $ch )
$freq [ $j ][ $i ] = $freq [ $j ][ $i - 1] + 1;
else
$freq [ $j ][ $i ] = $freq [ $j ][ $i - 1];
}
}
} // Function to return the frequency of the // given character in the sub-string $str[$l...$r] function getFrequency( $ch , $l , $r )
{ global $freq ;
if ( $l == 0)
return $freq [ord( $ch )][ $r ];
else
return ( $freq [ord( $ch )][ $r ] - $freq [ord( $ch )][ $l - 1]);
} // Function to return the last non-repeating character function lastNonRepeating( $str , $n , $l , $r )
{ // Starting from the last character
for ( $i = $r ; $i >= $l ; $i --)
{
// Current character
$ch = $str [ $i ];
// If frequency of the current character is 1
// then return the character
if (getFrequency( $ch , $l , $r ) == 1)
return $ch ;
}
// All the characters of the
// sub-string are repeating
return "-1" ;
} // Driver code $str = "GeeksForGeeks" ;
$n = strlen ( $str );
$queries = array ( array ( 2, 9 ), array ( 2, 3 ), array ( 0, 12 ) );
$q =3;
// Pre-calculate the frequency array preCalculate( $str , $n );
for ( $i = 0; $i < $q ; $i ++)
{ echo (lastNonRepeating( $str , $n ,
$queries [ $i ][0],
$queries [ $i ][1])), "\n" ;
} // This code is contributed by ihritik ?> |
<script> // JavaScript implementation of the approach // Maximum distinct characters possible let MAX = 256;
// To store the frequency of the characters
let freq;
// Function to pre-calculate the frequency array
function preCalculate(str,n)
{
// Only the first character has
// frequency 1 till index 0
freq[str[0].charCodeAt(0)][0] = 1;
// Starting from the second
// character of the string
for (let i = 1; i < n; i++) {
let ch = str[i];
// For every possible character
for (let j = 0; j < MAX; j++) {
// Current character under consideration
let charToUpdate = String.fromCharCode(j);
// If it is equal to the character
// at the current index
if (charToUpdate == ch)
freq[j][i] = freq[j][i - 1] + 1;
else
freq[j][i] = freq[j][i - 1];
}
}
}
// Function to return the frequency of the
// given character in the sub-string str[l...r]
function getFrequency(ch,l,r)
{
if (l == 0)
return freq[ch.charCodeAt(0)][r];
else
return (freq[ch.charCodeAt(0)][r] -
freq[ch.charCodeAt(0)][l - 1]);
}
// Function to return the last non-repeating character
function lastNonRepeating(str,n,l,r)
{
// Starting from the last character
for (let i = r; i >= l; i--) {
// Current character
let ch = str[i];
// If frequency of the current character is 1
// then return the character
if (getFrequency(ch, l, r) == 1)
return ( "" + ch);
}
// All the characters of the
// sub-string are repeating
return "-1" ;
}
// Driver code
let str = "GeeksForGeeks" ;
let n = str.length;
let queries = [[ 2, 9 ], [ 2, 3 ], [ 0, 12 ]];
let q = queries.length;
// Pre-calculate the frequency array
freq = new Array(MAX);
for (let i=0;i<MAX;i++)
{
freq[i]= new Array(n);
for (let j=0;j<n;j++)
{
freq[i][j]=0;
}
}
preCalculate(str, n);
for (let i = 0; i < q; i++) {
document.write(
lastNonRepeating(str, n,queries[i][0],queries[i][1])+
"<br>" );}
// This code is contributed by rag2127 </script> |
G k r
Time Complexity: O(256*N), as we are using nested loops for traversing 256*N times. Where N is the length of the string.
Auxiliary Space: O(256*1000), as we are using extra space for the frequency map.