You are given a 2D integer array intervals
, where intervals[i] = [left<sub>i</sub>, right<sub>i</sub>]
describes the i<sup>th</sup>
interval starting at left<sub>i</sub>
and ending at right<sub>i</sub>
(inclusive). The size of an interval is defined as the number of integers it contains, or more formally right<sub>i</sub> - left<sub>i</sub> + 1
.
You are also given an integer array queries
. The answer to the j<sup>th</sup>
query is the size of the smallest interval i
such that left<sub>i</sub> <= queries[j] <= right<sub>i</sub>
. If no such interval exists, the answer is -1
.
Return an array containing the answers to the queries.
Example 1:
Input: intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5]
Output: [3,3,1,4]
Explanation: The queries are processed as follows:
- Query = 2: The interval [2,4] is the smallest interval containing 2. The answer is 4 - 2 + 1 = 3.
- Query = 3: The interval [2,4] is the smallest interval containing 3. The answer is 4 - 2 + 1 = 3.
- Query = 4: The interval [4,4] is the smallest interval containing 4. The answer is 4 - 4 + 1 = 1.
- Query = 5: The interval [3,6] is the smallest interval containing 5. The answer is 6 - 3 + 1 = 4.
Example 2:
Input: intervals = [[2,3],[2,5],[1,8],[20,25]], queries = [2,19,5,22]
Output: [2,-1,4,6]
Explanation: The queries are processed as follows:
- Query = 2: The interval [2,3] is the smallest interval containing 2. The answer is 3 - 2 + 1 = 2.
- Query = 19: None of the intervals contain 19. The answer is -1.
- Query = 5: The interval [2,5] is the smallest interval containing 5. The answer is 5 - 2 + 1 = 4.
- Query = 22: The interval [20,25] is the smallest interval containing 22. The answer is 25 - 20 + 1 = 6.
How would you efficiently solve this problem?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method to find the smallest interval that includes each query involves checking every possible interval for each query. For each query, we look at every interval and see if the query falls within that interval. We then find the smallest such interval.
Here's how the algorithm would work step-by-step:
def min_interval_to_include_each_query_brute_force(intervals, queries):
results = []
for query in queries:
minimum_interval_length = float('inf')
for interval_start, interval_end in intervals:
# Check if the query is within the current interval
if interval_start <= query <= interval_end:
interval_length = interval_end - interval_start + 1
# Find the min interval length
minimum_interval_length = min(minimum_interval_length, interval_length)
#If no interval contains the query, return -1
if minimum_interval_length == float('inf'):
results.append(-1)
else:
results.append(minimum_interval_length)
return results
The best way to solve this puzzle efficiently involves keeping track of intervals and finding the smallest one that answers each question. We use a clever way of sorting and prioritizing to quickly locate the right intervals without checking everything.
Here's how the algorithm would work step-by-step:
def min_interval(intervals, queries):
interval_size = lambda interval: interval[1] - interval[0] + 1
intervals_sorted = sorted(intervals, key=interval_size)
queries_with_index = sorted([(query, index) for index, query in enumerate(queries)])
result = [0] * len(queries)
available_intervals = []
interval_index = 0
for query, query_index in queries_with_index:
# Add valid intervals to the heap.
while interval_index < len(intervals_sorted) and \
intervals_sorted[interval_index][0] <= query:
import heapq
heapq.heappush(available_intervals, \
(interval_size(intervals_sorted[interval_index]), \
intervals_sorted[interval_index]))
interval_index += 1
# Remove invalid intervals from the heap.
while available_intervals and available_intervals[0][1][1] < query:
import heapq
heapq.heappop(available_intervals)
# Assign the smallest valid interval size or -1 if none exists.
if available_intervals:
result[query_index] = available_intervals[0][0]
else:
result[query_index] = -1
return result
Case | How to Handle |
---|---|
Empty intervals or queries array | Return an empty array since there are no intervals or queries to process, respectively. |
Intervals with identical start and end points (single point intervals) | The solution should treat these intervals normally, considering their length as zero for length comparison. |
Queries array contains duplicate queries | The solution should handle duplicate queries correctly, potentially requiring storing results using a map to avoid redundant computations. |
Large number of intervals or queries (scalability) | Ensure the solution uses efficient data structures and algorithms (e.g., binary search, segment tree) to avoid time complexity issues. |
Queries outside the range of all intervals | Return -1 for such queries, as no interval includes them. |
Intervals with very large ranges (potential integer overflow) | Use appropriate data types (e.g., long) to prevent integer overflow when calculating interval lengths. |
Overlapping intervals, needing to find the minimum of overlapping options | The solution needs to consider all overlapping intervals and select the one with the minimum length that contains the query. |
Intervals are not sorted | Sort intervals based on their start values to enable efficient binary search for the overlapping intervals. |