Given an integer N which represents the total number of IDs present, a 2D array arr of size Mx2, where arr[i] = [ID, score] and 1D array query of size Q. We can assign multiple scores to a single ID. For each query q[i] where 0 <= i < Q, find the number of IDs who don’t have any scores within the range (query[i]/2, query[i]) where 0 <= i < Q.
Examples:
Input: N = 3, M = 4, arr[][] = [[1, 4], [2, 1], [1, 1], [3, 2]], query[] = [4, 2], Q =2
Output: [1, 0]
Explanation:
- For the first query, its value is 4, so we have to find the number of IDs whose scores do not lie between [4/2, 4]. Seeing in arr[][], ID 1 and 3 have scores lying between range but score of ID 2 doesn’t. Therefore for first query, the answer is 1.
- For the second query, its value is 2, so we have to find the number of IDs whose scores do not lie between [ 2/2, 2]. Seeing in arr[][] all IDs have scores lying between the range. Therefore for the second query, the answer is 0.
Input: N=2, M=4, arr[][] = [[2, 1], [1, 2], [1, 5], [2, 4]], query[] = [6, 10], Q = 2
Output: [0, 1]
Explanation:
- For the first query, its value is 6, so we need to find the number of IDs whose scores do not lie between [6/2, 6]. Seeing in arr[][], all IDs have scores lying between the range. Therefore for the first query, answer is 0.
- For the second query, its value is 10, so we need to find the number of IDs whose scores do not lie between [10/2, 10]. Seeing in arr[][], ID 1 has scores lying between the range but scores of ID 2 doesn’t. Therefore, for the second query, the answer is 1.
Approach: This can be solved with the following idea:
This can be solved by using a map as frequency array and two pointers algorithm. Instead of solving the queries in order of the input we can sort the queries and solve using two pointers. Sort the query and arr. For each query we try to maintain 2 pointers (start and end) which will maintain a window of only those scores (with IDs) which lie inside the query range. To get the answer of a query, we simply subtract the total number of IDs present (N) – IDs having values within the query range.
Below are the steps involved in the implementation of the code:
- Sort the 2-D array arr according to their scores in ascending order.
- Sort the array query in ascending order.
- Initialize a map freq which will help us to find frequency of element IDs lying in a range.
- Start Iterating through query array.
- For each query[i], we have to see how many IDs are present in the range.
- First, keep incrementing the frequency of IDs in freq by seeing their scores until query[i] maximum range is reached.
- Now keep decreasing the frequency of IDs in freq by seeing their scores until query[i] minimum range is reached. If for any ID, the frequency becomes 0, then delete it from freq map.
- Now for query[i], ans would be n – freq.size().
- Same for rest of the query elements.
Below is the implementation of the following code:
// C++ Implementation #include <bits/stdc++.h> using namespace std;
// Function to count number of elements // not in specified range void count( int n, vector<vector< int > >& arr,
vector< int >& query)
{ // vector to store the score with their IDs
vector<pair< int , int > > vp;
for ( int i = 0; i < arr.size(); i++) {
vp.push_back({ arr[i][1], arr[i][0] });
}
// vector to store the order of input queries
vector<pair< int , int > > vq;
int q = query.size();
for ( int i = 0; i < q; i++) {
vq.push_back({ query[i], i });
}
sort(vp.begin(), vp.end());
sort(vq.begin(), vq.end());
// map to store the frequency of IDs
map< int , int > freq;
vector< int > ans(q);
int l = 0, r = 0;
for ( int i = 0; i < q; i++) {
int query_number = vq[i].second;
int start = vq[i].first / 2;
int end = vq[i].first;
while (r < vp.size() && vp[r].first <= end) {
freq[vp[r].second]++;
r++;
}
while (l < vp.size() && vp[l].first < start) {
freq[vp[l].second]--;
if (freq[vp[l].second] == 0)
freq.erase(vp[l].second);
l++;
}
ans[query_number] = n - freq.size();
}
for ( int i = 0; i < q; i++)
cout << ans[i] << " ";
cout << "\n";
} // Driver code int main()
{ int N = 3;
vector<vector< int > > arr
= { { 1, 4 }, { 2, 1 }, { 1, 1 }, { 3, 2 } };
vector< int > query = { 4, 2 };
// Function call
count(N, arr, query);
return 0;
} |
// Java Implementation import java.util.*;
public class Main {
// Function to count number of elements not in specified range
public static void count( int n, List<List<Integer>> arr, List<Integer> query) {
// ArrayList to store the score with their IDs
List<Pair<Integer, Integer>> vp = new ArrayList<>();
for (List<Integer> list : arr) {
vp.add( new Pair<>(list.get( 1 ), list.get( 0 )));
}
// ArrayList to store the order of input queries
List<Pair<Integer, Integer>> vq = new ArrayList<>();
int q = query.size();
for ( int i = 0 ; i < q; i++) {
vq.add( new Pair<>(query.get(i), i));
}
// Sort both ArrayLists based on the first element
Collections.sort(vp, Comparator.comparingInt(o -> o.getKey()));
Collections.sort(vq, Comparator.comparingInt(Pair::getKey));
// HashMap to store the frequency of IDs
Map<Integer, Integer> freq = new HashMap<>();
int [] ans = new int [q];
int l = 0 , r = 0 ;
for ( int i = 0 ; i < q; i++) {
int queryNumber = vq.get(i).getValue();
int start = vq.get(i).getKey() / 2 ;
int end = vq.get(i).getKey();
while (r < vp.size() && vp.get(r).getKey() <= end) {
freq.put(vp.get(r).getValue(), freq.getOrDefault(vp.get(r).getValue(), 0 ) + 1 );
r++;
}
while (l < vp.size() && vp.get(l).getKey() < start) {
freq.put(vp.get(l).getValue(), freq.get(vp.get(l).getValue()) - 1 );
if (freq.get(vp.get(l).getValue()) == 0 ) {
freq.remove(vp.get(l).getValue());
}
l++;
}
ans[queryNumber] = n - freq.size();
}
// Print the result
for ( int i = 0 ; i < q; i++) {
System.out.print(ans[i] + " " );
}
System.out.println();
}
public static void main(String[] args) {
int N = 3 ;
List<List<Integer>> arr = Arrays.asList(
Arrays.asList( 1 , 4 ),
Arrays.asList( 2 , 1 ),
Arrays.asList( 1 , 1 ),
Arrays.asList( 3 , 2 )
);
List<Integer> query = Arrays.asList( 4 , 2 );
// Function call
count(N, arr, query);
}
// Helper class to store pairs
static class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
} // This code is contributed by Tapesh(tapeshdua420) |
from collections import defaultdict
# Function to count number of elements not in specified range def count(n, arr, query):
# List to store the score with their IDs
vp = [(arr[i][ 1 ], arr[i][ 0 ]) for i in range ( len (arr))]
# List to store the order of input queries
vq = [(query[i], i) for i in range ( len (query))]
vp.sort()
vq.sort()
# Dictionary to store the frequency of IDs
freq = defaultdict( int )
ans = [ 0 ] * len (query)
l = 0
r = 0
for i in range ( len (query)):
query_number = vq[i][ 1 ]
start = vq[i][ 0 ] / / 2
end = vq[i][ 0 ]
while r < len (vp) and vp[r][ 0 ] < = end:
freq[vp[r][ 1 ]] + = 1
r + = 1
while l < len (vp) and vp[l][ 0 ] < start:
freq[vp[l][ 1 ]] - = 1
if freq[vp[l][ 1 ]] = = 0 :
del freq[vp[l][ 1 ]]
l + = 1
ans[query_number] = n - len (freq)
for i in range ( len (query)):
print (ans[i], end = " " )
# Driver code if __name__ = = "__main__" :
N = 3
arr = [[ 1 , 4 ], [ 2 , 1 ], [ 1 , 1 ], [ 3 , 2 ]]
query = [ 4 , 2 ]
# Function call
count(N, arr, query)
|
// C# program for the above approach using System;
using System.Collections.Generic;
using System.Linq;
public class GFG {
// Function to count the number of elements
// not in the specified range
static void Count( int n, List<List< int > > arr,
List< int > query)
{
// List to store the score with their IDs
List<Tuple< int , int > > vp
= new List<Tuple< int , int > >();
for ( int i = 0; i < arr.Count; i++) {
vp.Add(
new Tuple< int , int >(arr[i][1], arr[i][0]));
}
// List to store the order of input queries
List<Tuple< int , int > > vq
= new List<Tuple< int , int > >();
int q = query.Count;
for ( int i = 0; i < q; i++) {
vq.Add( new Tuple< int , int >(query[i], i));
}
vp.Sort();
vq.Sort();
// Dictionary to store the frequency of IDs
Dictionary< int , int > freq
= new Dictionary< int , int >();
List< int > ans = new List< int >( new int [q]);
int l = 0, r = 0;
for ( int i = 0; i < q; i++) {
int queryNumber = vq[i].Item2;
int start = vq[i].Item1 / 2;
int end = vq[i].Item1;
while (r < vp.Count && vp[r].Item1 <= end) {
if (!freq.ContainsKey(vp[r].Item2)) {
freq[vp[r].Item2] = 0;
}
freq[vp[r].Item2]++;
r++;
}
while (l < vp.Count && vp[l].Item1 < start) {
freq[vp[l].Item2]--;
if (freq[vp[l].Item2] == 0) {
freq.Remove(vp[l].Item2);
}
l++;
}
ans[queryNumber] = n - freq.Count;
}
Console.WriteLine( string .Join( " " , ans));
}
// Driver code
static void Main()
{
int N = 3;
List<List< int > > arr = new List<List< int > >{
new List< int >{ 1, 4 }, new List< int >{ 2, 1 },
new List< int >{ 1, 1 }, new List< int >{ 3, 2 }
};
List< int > query = new List< int >{ 4, 2 };
// Function call
Count(N, arr, query);
}
} // This code is contributed by Susobhan Akhuli |
// JavaScript program for the above approach // Function to count number of elements // not in the specified range function count(n, arr, query) {
// Array to store the score with their IDs
let vp = [];
for (let i = 0; i < arr.length; i++) {
vp.push([arr[i][1], arr[i][0]]);
}
// Array to store the order of input queries
let vq = [];
let q = query.length;
for (let i = 0; i < q; i++) {
vq.push([query[i], i]);
}
vp.sort((a, b) => a[0] - b[0]);
vq.sort((a, b) => a[0] - b[0]);
// Map to store the frequency of IDs
let freq = new Map();
let ans = Array(q).fill(0);
let l = 0, r = 0;
for (let i = 0; i < q; i++) {
let queryNumber = vq[i][1];
let start = Math.floor(vq[i][0] / 2);
let end = vq[i][0];
while (r < vp.length && vp[r][0] <= end) {
freq.set(vp[r][1], (freq.get(vp[r][1]) || 0) + 1);
r++;
}
while (l < vp.length && vp[l][0] < start) {
freq.set(vp[l][1], freq.get(vp[l][1]) - 1);
if (freq.get(vp[l][1]) === 0) {
freq. delete (vp[l][1]);
}
l++;
}
ans[queryNumber] = n - freq.size;
}
console.log(ans.join( " " ));
} // Driver code let N = 3; let arr = [ [1, 4],
[2, 1],
[1, 1],
[3, 2]
]; let query = [4, 2]; // Function call count(N, arr, query); // This code is contributed by Susobhan Akhuli |
1 0
Complexity Analysis:
Time Complexity: O(M log M + Q log Q )
Auxiliary Space: O(M + Q)
where M is the size of 2D array arr, and Q is the number of queries