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:

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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]));
        }
    }
}

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

G
e
F


My Personal Notes arrow_drop_up

Strategy Path planning and Destination matters in success No need to worry about in between temporary failures

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01