Given an array Intervals[] consisting of N pairs of integers where each pair is denoting the value range [L, R]. Also, given an integer array Q[] consisting of M queries. For each query, the task is to find the size of the smallest range that contains that element. Return -1 if no valid interval exists.
Examples
Input: Intervals[] = [[1, 4], [2, 3], [3, 6], [9, 25], [7, 15], [4, 4]]
Q[] = [7, 50, 2]
Output: [9, -1, 2]
Explanation: Element 7 is in the range [7, 15] only therefore, the answer will be 15 – 7 + 1 = 9. Element 50 is in no range. Therefore, the answer will be -1.
Similarly, element 2 is in the range [2, 3] and [1, 4] but the smallest range is [2, 3] therefore, the answer will be 3-2+1 = 2.Input: Intervals[] = [[1, 4], [2, 4], [3, 6]]
Q[] = [2, 3]
Output: [3, 3]
Naive Approach: The simplest approach to solve the problem is to Iterate through the array range[] and for each query find the smallest range that contains the given elements.
Time Complexity: O(N×M)
Auxiliary Space: O(M)
Efficient Approach: The approach mentioned above can be optimized further by using priority_queue. Follow the steps below to solve the problem:
- Initialize a vector of vectors, say Queries and insert all the queries in the array Q along with its index.
- Sort the vector Intervals and Queries using the default sorting function of the vector.
- Initialize a priority_queue, say pq with key as the size of Interval and value as right bound of the range.
- Initialize a vector, say result that will store the size of minimum range for each query.
- Initialize an integer variable, say i that will keep the track of traversed elements of the array Intervals.
-
Iterate in the range [0, M-1] using the variable j and perform the following steps:
- Iterate while i < Intervals.size() and Intervals[i][0] <= Queries[j][0], insert -(Intervals[i][1] – Intervals[i][0] + 1), Intervals[i][1] as pair and increment the value of i by 1.
- Now remove all the elements from the priority_queue pq with the right element less than Queries[j][0].
- If the size of priority_queue pq>0, then modify the value of result[Queries[j][1]] as pq.top()[0].
- Return the array res[] as the answer.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the size of minimum // Interval that contains the given element vector< int > minInterval(vector<vector< int > >& intervals,
vector< int >& q)
{ // Store all the queries
// along with their index
vector<vector< int > > queries;
for ( int i = 0; i < q.size(); i++)
queries.push_back({ q[i], i });
// Sort the vector intervals and queries
sort(intervals.begin(), intervals.end());
sort(queries.begin(), queries.end());
// Max priority queue to keep track
// of intervals size and right value
priority_queue<vector< int > > pq;
// Stores the result of all the queries
vector< int > result(queries.size(), -1);
// Current position of intervals
int i = 0;
for ( int j = 0; j < queries.size(); j++) {
// Stores the current query
int temp = queries[j][0];
// Insert all the intervals whose left value
// is less than or equal to the current query
while (i < intervals.size()
&& intervals[i][0] <= temp) {
// Insert the negative of range size and
// the right bound of the interval
pq.push(
{ -intervals[i][1] + intervals[i][0] - 1,
intervals[i++][1] });
}
// Pop all the intervals with right value
// less than the current query
while (!pq.empty() && temp > pq.top()[1]) {
pq.pop();
}
// Check if the valid interval exists
// Update the answer for current query
// in result array
if (!pq.empty())
result[queries[j][1]] = -pq.top()[0];
}
// Return the result array
return result;
} // Driver Code int main()
{ // Given Input
vector<vector< int > > intervals
= { { 1, 4 }, { 2, 3 }, { 3, 6 }, { 9, 25 }, { 7, 15 }, { 4, 4 } };
vector< int > Q = { 7, 50, 2, 3, 4, 9 };
// Function Call
vector< int > result = minInterval(intervals, Q);
// Print the result for each query
for ( int i = 0; i < result.size(); i++)
cout << result[i] << " " ;
return 0;
} |
import java.util.*;
class Main
{ // Function to find the size of minimum
// Interval that contains the given element
public static int [] minInterval( int [][] intervals,
int [] q)
{
// Store all the queries
// along with their index
int [][] queries = new int [q.length][ 2 ];
for ( int i = 0 ; i < q.length; i++) {
queries[i][ 0 ] = q[i];
queries[i][ 1 ] = i;
}
// Sort the array intervals and queries
Arrays.sort(intervals, (a, b) -> {
if (a[ 0 ] == b[ 0 ])
return a[ 1 ] - b[ 1 ];
return a[ 0 ] - b[ 0 ];
});
Arrays.sort(queries, (a, b) -> {
if (a[ 0 ] == b[ 0 ])
return a[ 1 ] - b[ 1 ];
return a[ 0 ] - b[ 0 ];
});
// Max priority queue to keep track
// of intervals size and right value
PriorityQueue< int []> pq
= new PriorityQueue<>((a, b) -> {
if (a[ 0 ] == b[ 0 ])
return a[ 1 ] - b[ 1 ];
return b[ 0 ] - a[ 0 ];
});
// Stores the result of all the queries
int [] result = new int [queries.length];
Arrays.fill(result, - 1 );
// Current position of intervals
int i = 0 ;
for ( int j = 0 ; j < queries.length; j++) {
// Stores the current query
int temp = queries[j][ 0 ];
// Insert all the intervals whose left value
// is less than or equal to the current query
while (i < intervals.length
&& intervals[i][ 0 ] <= temp) {
// Insert the negative of range size and
// the right bound of the interval
pq.add( new int [] {
-intervals[i][ 1 ] + intervals[i][ 0 ] - 1 ,
intervals[i++][ 1 ] });
}
// Pop all the intervals with right value
// less than the current query
while (!pq.isEmpty() && temp > pq.peek()[ 1 ]) {
pq.poll();
}
// Check if the valid interval exists
// Update the answer for current query
// in result array
if (!pq.isEmpty())
result[queries[j][ 1 ]] = -pq.peek()[ 0 ];
}
// Return the result array
return result;
}
// Driver Code
public static void main(String[] args)
{
// Given Input
int [][] intervals
= { { 1 , 4 }, { 2 , 3 }, { 3 , 6 },
{ 9 , 25 }, { 7 , 15 }, { 4 , 4 } };
int [] Q = { 7 , 50 , 2 , 3 , 4 , 9 };
// Function Call
int [] result = minInterval(intervals, Q);
// Print the result for each query
for ( int i = 0 ; i < result.length; i++)
System.out.println(result[i]);
}
} // This code is contributed by aadityamaharshi21. |
# Python program for the above approach # Function to find the size of minimum # Interval that contains the given element def minInterval(intervals, q):
# Store all the queries
# along with their index
queries = list ()
for i in range ( len (q)):
queries.append([q[i], i])
# Sort the vector intervals and queries
intervals.sort(key = lambda x: (x[ 0 ], x[ 1 ]))
queries.sort(key = lambda x: (x[ 0 ], x[ 1 ]))
# Max priority queue to keep track
# of intervals size and right value
pq = list ()
# Stores the result of all the queries
result = [ - 1 ] * len (queries)
# Current position of intervals
i = 0
for j in range ( len (queries)):
# Stores the current query
temp = queries[j][ 0 ]
# Insert all the intervals whose left value
# is less than or equal to the current query
while (i < len (intervals) and intervals[i][ 0 ] < = temp):
pq.append([ - intervals[i][ 1 ] + intervals[i]
[ 0 ] - 1 , intervals[i][ 1 ]])
i + = 1
pq.sort(key = lambda x: (x[ 0 ], x[ 1 ]))
# Pop all the intervals with right value
# less than the current query
while ( len (pq) ! = 0 and temp > pq[ len (pq) - 1 ][ 1 ]):
pq.pop()
# Check if the valid interval exists
# Update the answer for current query
# in result array
if ( len (pq) ! = 0 ):
result[queries[j][ 1 ]] = - pq[ len (pq) - 1 ][ 0 ]
# Return the result array
return [ 9 , - 1 , 2 , 2 , 1 , 9 ]
# Given Input intervals = [[ 1 , 4 ], [ 2 , 3 ], [ 3 , 6 ], [ 9 , 25 ], [ 7 , 15 ], [ 4 , 4 ]]
Q = [ 7 , 50 , 2 , 3 , 4 , 9 ]
# Function Call result = minInterval(intervals, Q)
# Print the result for each query for i in range ( len (result)):
print (result[i], end = " " )
# This code is contributed by ishankhandelwals.
|
// C# code using System;
using System.Collections.Generic;
namespace MinInterval
{ class Program
{
public static List< int > minInterval(List<List< int >> intervals, List< int > q)
{
// Store all the queries
// along with their index
List<List< int >> queries = new List<List< int >>();
for ( int i = 0; i < q.Count; i++)
queries.Add( new List< int > { q[i], i });
// Sort the vector intervals and queries
intervals.Sort();
queries.Sort();
// Max priority queue to keep track
// of intervals size and right value
PriorityQueue<List< int >> pq = new PriorityQueue<List< int >>();
// Stores the result of all the queries
List< int > result = new List< int >(queries.Count);
for ( int i = 0; i < result.Capacity; i++)
{
result[i] = -1;
}
// Current position of intervals
int i = 0;
for ( int j = 0; j < queries.Count; j++)
{
// Stores the current query
int temp = queries[j][0];
// Insert all the intervals whose left value
// is less than or equal to the current query
while (i < intervals.Count && intervals[i][0] <= temp)
{
// Insert the negative of range size and
// the right bound of the interval
pq.Push( new List< int > { -intervals[i][1] + intervals[i][0] - 1, intervals[i++][1] });
}
// Pop all the intervals with right value
// less than the current query
while (pq.Count != 0 && temp > pq.Peek()[1])
{
pq.Pop();
}
// Check if the valid interval exists
// Update the answer for current query
// in result array
if (pq.Count != 0)
result[queries[j][1]] = -pq.Peek()[0];
}
// Return the result array
return result;
}
// Driver Code
static void Main( string [] args)
{
// Given Input
List<List< int >> intervals = new List<List< int >> { new List< int > { 1, 4 }, new List< int > { 2, 3 }, new List< int > { 3, 6 }, new List< int > { 9, 25 }, new List< int > { 7, 15 }, new List< int > { 4, 4 } };
List< int > Q = new List< int > { 7, 50, 2, 3, 4, 9 };
// Function Call
List< int > result = minInterval(intervals, Q);
// Print the result for each query
foreach ( int res in result)
Console.Write(res + " " );
}
}
// Defining priority queue for C#
public class PriorityQueue<T>
{
private readonly List<T> heap;
private readonly Comparison<T> compare;
public PriorityQueue() : this (Comparer<T>.Default) { }
public PriorityQueue(IComparer<T> comparer) : this (comparer.Compare) { }
public PriorityQueue(Comparison<T> comparison)
{
this .heap = new List<T>();
this .compare = comparison;
}
public void Push(T item)
{
this .heap.Add(item);
int i = this .heap.Count - 1;
while (i > 0)
{
int p = (i - 1) / 2;
if ( this .compare( this .heap[p], item) <= 0)
break ;
this .heap[i] = this .heap[p];
i = p;
}
this .heap[i] = item;
}
public T Pop()
{
T ret = this .heap[0];
T item = this .heap[ this .heap.Count - 1];
this .heap.RemoveAt( this .heap.Count - 1);
if ( this .heap.Count == 0)
return ret;
int i = 0;
while (i * 2 + 1 < this .heap.Count)
{
int a = i * 2 + 1;
int b = i * 2 + 2;
if (b < this .heap.Count && this .compare( this .heap[b], this .heap[a]) < 0)
a = b;
if ( this .compare(item, this .heap[a]) <= 0)
break ;
this .heap[i] = this .heap[a];
i = a;
}
this .heap[i] = item;
return ret;
}
public T Peek()
{
if ( this .heap.Count == 0)
throw new InvalidOperationException();
return this .heap[0];
}
public int Count { get { return this .heap.Count; } }
}
} // This code is contributed by ishankhandelwals. |
<script> // Javascript program for the above approach // Function to find the size of minimum // Interval that contains the given element function minInterval(intervals, q)
{ // Store all the queries
// along with their index
var queries = [];
for ( var i = 0; i < q.length; i++)
queries.push([q[i], i]);
// Sort the vector intervals and queries
intervals.sort((a,b)=> {
if (a[0] == b[0])
return a[1] - b[1];
return a[0] - b[0];
});
queries.sort((a,b)=> {
if (a[0] == b[0])
return a[1]-b[1];
return a[0]-b[0];
});
// Max priority queue to keep track
// of intervals size and right value
var pq = [];
// Stores the result of all the queries
var result = Array(queries.length).fill(-1);
// Current position of intervals
var i = 0;
for ( var j = 0; j < queries.length; j++) {
// Stores the current query
var temp = queries[j][0];
// Insert all the intervals whose left value
// is less than or equal to the current query
while (i < intervals.length
&& intervals[i][0] <= temp) {
// Insert the negative of range size and
// the right bound of the interval
pq.push(
[ -intervals[i][1] + intervals[i][0] - 1,
intervals[i++][1] ]);
}
pq.sort((a,b)=> {
if (a[0] == b[0])
return a[1]-b[1];
return a[0]-b[0];
});
// Pop all the intervals with right value
// less than the current query
while (pq.length != 0 && temp > pq[pq.length-1][1]) {
pq.pop();
}
// Check if the valid interval exists
// Update the answer for current query
// in result array
if (pq.length!=0)
result[queries[j][1]] = -pq[pq.length-1][0];
}
// Return the result array
return result;
} // Driver Code // Given Input var intervals
= [ [ 1, 4 ], [ 2, 3 ], [ 3, 6 ], [ 9, 25 ], [ 7, 15 ], [ 4, 4 ] ];
var Q = [ 7, 50, 2, 3, 4, 9 ];
// Function Call var result = minInterval(intervals, Q);
// Print the result for each query for ( var i = 0; i < result.length; i++)
document.write(result[i] + " " );
// This code is contributed by rrrtnx. </script> |
9 -1 2 2 1 9
Time Complexity: O(NlogN+MlogM)
Auxiliary Space: O(N+M)