Related Articles
Queries to find the last non-repeating character in the sub-string of a given string
• Difficulty Level : Hard
• Last Updated : 25 Sep, 2019

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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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

 `// C++ implementation of the approach ``#include``using` `namespace` `std;`` ` `// Maximum distinct characters possible ``int` `MAX = 256; `` ` `// To store the frequency of the characters ``int` `freq = {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] = 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 = { { 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], ``                            ``queries[i]))<

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

 `# 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 conributed 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] = 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

 `= ``\$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``], ``                        ``\$queries``[``\$i``])), ``"\n"``; ``} `` ` ` ` `// This code is contributed by ihritik`` ` `?>`
Output:
```G
k
r
```

My Personal Notes arrow_drop_up