Queries to find the last non-repeating character in the sub-string of a given string
Last Updated :
22 Jun, 2022
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++
// 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
// 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 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 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
// 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
?>
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)][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>
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.
Similar Reads
Find the last non repeating character in string
Given a string str, the task is to find the last non-repeating character in it. For example, if the input string is "GeeksForGeeks", then the output should be 'r' and if the input string is "GeeksQuiz" then the output should be 'z'. if there is no non-repeating character then print -1.Examples: Inpu
5 min read
Find the Nth occurrence of a character in the given String
Given string str, a character ch, and a value N, the task is to find the index of the Nth occurrence of the given character in the given string. Print -1 if no such occurrence exists. Examples: Input: str = "Geeks", ch = 'e', N = 2 Output: 2 Input: str = "GFG", ch = 'e', N = 2 Output: -1 Recommended
7 min read
Queries to find total number of duplicate character in range L to R in the string S
Given a string S of size N consisting of lower case alphabets and an integer Q which represents the number of queries for S. Our task is to print the number of duplicate characters in the substring L to R for all the queries Q.Note: 1 ?N ? 106 and 1 ? Q? 106 Examples: Input : S = "geeksforgeeks", Q
9 min read
Find the Longest Non-Prefix-Suffix Substring in the Given String
Given a string s of length n. The task is to determine the longest substring t such that t is neither the prefix nor the suffix of string s, and that substring must appear as both prefix and suffix of the string s. If no such string exists, print -1. Example: Input: s = "fixprefixsuffix"Output: fix
7 min read
Print the frequency of adjacent repeating characters in given string
Given a string str of length N. The task is to print the frequency of adjacent repeating characters. Examples: Input: str = "Hello"Output: l: 2Explanation: Consecutive Repeating Character from the given string is "l" and its frequency is 2. Input: str = "Hellolllee"Output: l: 2 l: 3 e: 2Explanation:
5 min read
Queries to find number of indexes where characters repeated twice in row in substring L to R
Given string S of size N consisting of lower case characters and 2d array Q[][2] of size M representing several queries of type {L, R} representing a range. The task for this problem is for each query {L, R} to find several indexes where characters are repeated twice in a row in substring L to R. Ex
10 min read
Subsequences of given string consisting of non-repeating characters
Given a string str of length N, the task is to print all possible distinct subsequences of the string str which consists of non-repeating characters only. Examples: Input: str = "abac" Output: a ab abc ac b ba bac bc c Explanation: All possible distinct subsequences of the strings are { a, aa, aac,
7 min read
First non-repeating character of given string
Given a string s of lowercase English letters, the task is to find the first non-repeating character. If there is no such character, return '$'.Examples: Input: s = "geeksforgeeks"Output: 'f'Explanation: 'f' is the first character in the string which does not repeat.Input: s = "racecar"Output: 'e'Ex
9 min read
Print the string after the specified character has occurred given no. of times
Given a string, a character, and a count, the task is to print the string after the specified character has occurred count number of times. Print "Empty string" in case of any unsatisfying conditions. (Given character is not present, or present but less than given count, or given count completes on
5 min read
Javascript Program To Find Length Of The Longest Substring Without Repeating Characters
Given a string str, find the length of the longest substring without repeating characters. For âABDEFGABEFâ, the longest substring are âBDEFGAâ and "DEFGAB", with length 6.For âBBBBâ the longest substring is âBâ, with length 1.For "GEEKSFORGEEKS", there are two longest substrings shown in the below
5 min read