Queries to find the first non-repeating character in the sub-string of a string
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 first 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[] = {{0, 3}, {2, 3}, {5, 12}}
Output:
G
e
F
Sub-string for the queries are “Geek”, “ek” and “ForGeeks” and their first non-repeating characters are ‘G’, ‘e’ and ‘F’ respectively.Input: str = “xxyyxx”, q[] = {{2, 3}, {3, 4}}
Output:
-1
y
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 first 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++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Maximum distinct characters possible #define MAX 256 // To store the frequency of the characters int freq[MAX][MAX]; // 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 = 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]); } // Function to return the first // non-repeating character in range[l..r] string firstNonRepeating(string str, int n, int l, int r) { char t[2] = "" ; // Starting from the first character for ( int i = l; i < r; 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) { t[0] = ch; return t; } } // All the characters of the // sub-string are repeating return "-1" ; } // Driver code int main() { string str = "GeeksForGeeks" ; int n = str.length(); int queries[][2] = {{0, 3}, {2, 3}, {5, 12}}; int q = sizeof (queries) / sizeof (queries[0]); // Pre-calculate the frequency array freq[MAX][n] = {0}; preCalculate(str, n); for ( int i = 0; i < q; i++) cout << firstNonRepeating(str, n, queries[i][0], queries[i][1]) << endl; return 0; } // This code is contributed by // sanjeev2552 |
Java
// 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 first non-repeating character in range[l..r] static String firstNonRepeating(String str, int n, int l, int r) { // Starting from the first character for ( int i = l; i < r; 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[][] = { { 0 , 3 }, { 2 , 3 }, { 5 , 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(firstNonRepeating(str, n, queries[i][ 0 ], queries[i][ 1 ])); } } } |
Python3
# Python3 implementation of the approach # Maximum distinct characters possible MAX = 256 # To store the frequency of the characters freq = [[ 0 for i in range ( MAX )] for j in range ( MAX )] # 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 first # non-repeating character in range[l..r] def firstNonRepeating(string, n, l, r): t = [""] * 2 # Starting from the first character for i in range (l, r): # Current character ch = string[i] # If frequency of the current character is 1 # then return the character if getFrequency(ch, l, r) = = 1 : t[ 0 ] = ch return t[ 0 ] # All the characters of the # sub-string are repeating return "-1" # Driver Code if __name__ = = "__main__" : string = "GeeksForGeeks" n = len (string) queries = [( 0 , 3 ), ( 2 , 3 ), ( 5 , 12 )] q = len (queries) # Pre-calculate the frequency array preCalculate(string, n) for i in range (q): print (firstNonRepeating(string, n, queries[i][ 0 ], queries[i][ 1 ])) # This code is contributed by # sanjeev2552 |
C#
// 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 first non-repeating character in range[l..r] static string firstNonRepeating( string str, int n, int l, int r) { // Starting from the first character for ( int i = l; i < r; 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 = { { 0, 3 }, { 2, 3 }, { 5, 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(firstNonRepeating(str, n, queries[i,0], queries[i,1])); } } } // This code is contributed by AnkitRai01 |
Javascript
<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] = 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()][r]; else return (freq[ch.charCodeAt()][r] - freq[ch.charCodeAt()][l - 1]); } // Function to return the first non-repeating character in range[l..r] function firstNonRepeating(str, n, l, r) { // Starting from the first character for (let i = l; i < r; 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" ; } let str = "GeeksForGeeks" ; let n = str.length; let queries = [ [ 0, 3 ], [ 2, 3 ], [ 5, 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(firstNonRepeating(str, n, queries[i][0], queries[i][1]) + "</br>" ); } </script> |
G e F
Time Complexity: O(Q * N * MAX), where Q is the number of queries, N is the length of the string and MAX is the number of possible distinct characters.
Space Complexity: O(N * MAX), where N is the length of the string and MAX is the number of possible distinct characters.
Please Login to comment...