Given an array of N elements and Q queries, where each query contains an integer K. For each query, the task is to find the number of distinct integers in the suffix from Kth element to Nth element.
Input :
N=5, Q=3
arr[] = {2, 4, 6, 10, 2}
1
3
2
Output :
4
3
4
Approach:
The problem can be solved by precomputing the solution for all index from N-1 to 0. The idea is to use an unordered_set in C++ as set does not allow duplicate elements.
Traverse the array from end and add the current element into a set and the answer for the current index would be the size of the set. So, store the size of set at current index in an auxiliary array say suffixCount.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void printQueries( int n, int a[], int q, int qry[])
{
unordered_set< int > occ;
int suffixCount[n + 1];
for ( int i = n - 1; i >= 0; i--) {
occ.insert(a[i]);
suffixCount[i + 1] = occ.size();
}
for ( int i = 0; i < q; i++)
cout << suffixCount[qry[i]] << endl;
}
int main()
{
int n = 5, q = 3;
int a[n] = { 2, 4, 6, 10, 2 };
int qry[q] = { 1, 3, 2 };
printQueries(n, a, q, qry);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void printQueries( int n, int a[], int q, int qry[])
{
HashSet<Integer> occ = new HashSet<>();
int []suffixCount = new int [n + 1 ];
for ( int i = n - 1 ; i >= 0 ; i--)
{
occ.add(a[i]);
suffixCount[i + 1 ] = occ.size();
}
for ( int i = 0 ; i < q; i++)
System.out.println(suffixCount[qry[i]]);
}
public static void main(String args[])
{
int n = 5 , q = 3 ;
int a[] = { 2 , 4 , 6 , 10 , 2 };
int qry[] = { 1 , 3 , 2 };
printQueries(n, a, q, qry);
}
}
|
Python3
def printQueries(n, a, q, qry):
occ = dict ()
suffixCount = [ 0 for i in range (n + 1 )]
for i in range (n - 1 , - 1 , - 1 ):
occ[a[i]] = 1
suffixCount[i + 1 ] = len (occ)
for i in range (q):
print (suffixCount[qry[i]])
n = 5
q = 3
a = [ 2 , 4 , 6 , 10 , 2 ]
qry = [ 1 , 3 , 2 ]
printQueries(n, a, q, qry)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static void printQueries( int n, int []a, int q, int []qry)
{
HashSet< int > occ = new HashSet< int >();
int []suffixCount = new int [n + 1];
for ( int i = n - 1; i >= 0; i--)
{
occ.Add(a[i]);
suffixCount[i + 1] = occ.Count;
}
for ( int i = 0; i < q; i++)
Console.WriteLine(suffixCount[qry[i]]);
}
public static void Main(String []args)
{
int n = 5, q = 3;
int []a = { 2, 4, 6, 10, 2 };
int []qry = { 1, 3, 2 };
printQueries(n, a, q, qry);
}
}
|
PHP
<?php
function printQueries( $n , $a , $q , $qry )
{
$occ = array ();
$suffixCount = array_fill (0, $n + 1, 0);
for ( $i = $n - 1; $i >= 0; $i --)
{
array_push ( $occ , $a [ $i ]);
# give array of distinct element
$occ = array_unique ( $occ );
$suffixCount [ $i + 1] = sizeof( $occ );
}
for ( $i = 0; $i < $q ; $i ++)
echo $suffixCount [ $qry [ $i ]], "\n" ;
}
$n = 5;
$q = 3;
$a = array (2, 4, 6, 10, 2);
$qry = array (1, 3, 2);
printQueries( $n , $a , $q , $qry );
?>
|
Javascript
<script>
function printQueries(n,a,q,qry)
{
let occ = new Set();
let suffixCount = new Array(n + 1);
for (let i = n - 1; i >= 0; i--)
{
occ.add(a[i]);
suffixCount[i + 1] = occ.size;
}
for (let i = 0; i < q; i++)
document.write(suffixCount[qry[i]]+ "<br>" );
}
let n = 5, q = 3;
let a=[2, 4, 6, 10, 2];
let qry=[ 1, 3, 2 ];
printQueries(n, a, q, qry);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Approach without STL: Since queries need to be addressed, precomputation needs to be done. Otherwise, a simple traversal over the suffix would have sufficed.
An auxiliary array aux[] is maintained from the right side of the array. An array mark[] stores whether an element has occurred or not in the suffix traversed yet. If the element has not occurred, then update aux[i] = aux[i+1] + 1. Otherwise aux[i] = aux[i+1].
Answer for every query would be aux[q[i]].
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
#define MAX 100002
using namespace std;
void printUniqueElementsInSuffix( const int * arr,
int n, const int * q, int m)
{
int aux[MAX];
int mark[MAX];
memset (mark, 0, sizeof (mark));
aux[n - 1] = 1;
mark[arr[n - 1]] = 1;
for ( int i = n - 2; i >= 0; i--) {
if (mark[arr[i]] == 0) {
aux[i] = aux[i + 1] + 1;
mark[arr[i]] = 1;
}
else {
aux[i] = aux[i + 1];
}
}
for ( int i = 0; i < m; i++) {
cout << aux[q[i] - 1] << "\n" ;
}
}
int main()
{
int arr[] = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
int n = sizeof (arr) / sizeof (arr[0]);
int q[] = { 1, 3, 6 };
int m = sizeof (q) / sizeof (q[0]);
printUniqueElementsInSuffix(arr, n, q, m);
return 0;
}
|
Java
class GFG
{
static int MAX = 100002 ;
static void printUniqueElementsInSuffix( int [] arr,
int n, int [] q, int m)
{
int []aux = new int [MAX];
int []mark = new int [MAX];
aux[n - 1 ] = 1 ;
mark[arr[n - 1 ]] = 1 ;
for ( int i = n - 2 ; i >= 0 ; i--)
{
if (mark[arr[i]] == 0 )
{
aux[i] = aux[i + 1 ] + 1 ;
mark[arr[i]] = 1 ;
}
else
{
aux[i] = aux[i + 1 ];
}
}
for ( int i = 0 ; i < m; i++)
{
System.out.println(aux[q[i] - 1 ] );
}
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 1 , 2 , 3 , 4 , 10000 , 999 };
int n = arr.length;
int q[] = { 1 , 3 , 6 };
int m = q.length;
printUniqueElementsInSuffix(arr, n, q, m);
}
}
|
Python3
MAX = 100002 ;
def printUniqueElementsInSuffix(arr, n, q, m):
aux = [ 0 ] * MAX ;
mark = [ 0 ] * MAX ;
aux[n - 1 ] = 1 ;
mark[arr[n - 1 ]] = 1 ;
for i in range (n - 2 , - 1 , - 1 ):
if (mark[arr[i]] = = 0 ):
aux[i] = aux[i + 1 ] + 1 ;
mark[arr[i]] = 1 ;
else :
aux[i] = aux[i + 1 ];
for i in range (m):
print (aux[q[i] - 1 ]);
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 4 , 1 , 2 , 3 , 4 , 10000 , 999 ];
n = len (arr);
q = [ 1 , 3 , 6 ];
m = len (q);
printUniqueElementsInSuffix(arr, n, q, m);
|
C#
using System;
class GFG
{
static int MAX = 100002;
static void printUniqueElementsInSuffix( int [] arr,
int n, int [] q, int m)
{
int []aux = new int [MAX];
int []mark = new int [MAX];
aux[n - 1] = 1;
mark[arr[n - 1]] = 1;
for ( int i = n - 2; i >= 0; i--)
{
if (mark[arr[i]] == 0)
{
aux[i] = aux[i + 1] + 1;
mark[arr[i]] = 1;
}
else
{
aux[i] = aux[i + 1];
}
}
for ( int i = 0; i < m; i++)
{
Console.WriteLine(aux[q[i] - 1] );
}
}
static public void Main ()
{
int []arr = { 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 };
int n = arr.Length;
int []q = { 1, 3, 6 };
int m = q.Length;
printUniqueElementsInSuffix(arr, n, q, m);
}
}
|
Javascript
<script>
var MAX = 100002;
function printUniqueElementsInSuffix(arr, n, q, m)
{
var aux =[] ;
var mark = [];
aux.length = MAX ;
mark.length = MAX ;
aux.fill(0);
mark.fill(0);
aux[n - 1] = 1;
mark[arr[n - 1]] = 1;
for ( var i = n - 2; i >= 0; i--)
{
if (mark[arr[i]] == 0)
{
aux[i] = aux[i + 1] + 1;
mark[arr[i]] = 1;
}
else
{
aux[i] = aux[i + 1];
}
}
for ( var i = 0; i < m; i++)
{
document.write(aux[q[i] - 1] , "<br>" );
}
}
var arr = [ 1, 2, 3, 4, 1, 2, 3, 4, 10000, 999 ]
var n = arr.length;
var q = [ 1, 3, 6 ];
var m = q.length;
printUniqueElementsInSuffix(arr, n, q, m);
</script>
|
Time Complexity: O(n + m). where n and m are the sizes of the given input arrays.
Auxiliary Space: O(MAX)