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++
#include <bits/stdc++.h>
using namespace std;
void count( int n, vector<vector< int > >& arr,
vector< int >& query)
{
vector<pair< int , int > > vp;
for ( int i = 0; i < arr.size(); i++) {
vp.push_back({ arr[i][1], arr[i][0] });
}
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< 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";
}
int main()
{
int N = 3;
vector<vector< int > > arr
= { { 1, 4 }, { 2, 1 }, { 1, 1 }, { 3, 2 } };
vector< int > query = { 4, 2 };
count(N, arr, query);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static void count( int n, List<List<Integer>> arr, List<Integer> query) {
List<Pair<Integer, Integer>> vp = new ArrayList<>();
for (List<Integer> list : arr) {
vp.add( new Pair<>(list.get( 1 ), list.get( 0 )));
}
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));
}
Collections.sort(vp, Comparator.comparingInt(o -> o.getKey()));
Collections.sort(vq, Comparator.comparingInt(Pair::getKey));
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();
}
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 );
count(N, arr, query);
}
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;
}
}
}
|
Python3
from collections import defaultdict
def count(n, arr, query):
vp = [(arr[i][ 1 ], arr[i][ 0 ]) for i in range ( len (arr))]
vq = [(query[i], i) for i in range ( len (query))]
vp.sort()
vq.sort()
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 = " " )
if __name__ = = "__main__" :
N = 3
arr = [[ 1 , 4 ], [ 2 , 1 ], [ 1 , 1 ], [ 3 , 2 ]]
query = [ 4 , 2 ]
count(N, arr, query)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG {
static void Count( int n, List<List< int > > arr,
List< int > query)
{
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<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< 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));
}
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 };
Count(N, arr, query);
}
}
|
Javascript
function count(n, arr, query) {
let vp = [];
for (let i = 0; i < arr.length; i++) {
vp.push([arr[i][1], arr[i][0]]);
}
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]);
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( " " ));
}
let N = 3;
let arr = [
[1, 4],
[2, 1],
[1, 1],
[3, 2]
];
let query = [4, 2];
count(N, arr, query);
|
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
|