Find Next Optimal Range in Array
Last Updated :
06 Dec, 2023
Given an array ranges[][] of size N x 2, where for every i, range[i][0] is the start and range[i][1] is the end of the range. For every range, find the index of the Next Optimal Range. For a range i which ends at a point X, all the ranges that have their starting points >= X will be the Next Optimal Range. In the case of multiple Next Optimal Range, the range with the smallest starting point is the most optimal. If there is no optimal range of any index i, then the answer for i-th index will be -1.
Note: The ranges have unique starting points.
Examples:
Input: ranges = [[-1, -1], [-2, 3], [3, 3]]
Output: [0,2,2]
Explanation: For i = 0, start = -1 and end = -1, so the only range which starts at or after -1, is the range [3, 3] which is at index 0.For i = 1, start = -2 and end = 3, so the only range which starts at or after 3, is the range [3, 3], which is at index. For i = 2, start = 3 and end = 3, so the only range which starts at or after 3, is the range [3, 3], which is at index 2.
Input: ranges = [[-1, -1], [2, 3], [-3, 3], [-50, -20]]
Output: [1, -1, -1, 2]
Explanation: For i = 0, start = -1 and end = -1, so the only range which starts after at or after -1, is the range [2, 3] which is at index 1.For i = 1, start = 2 and end = 3, so no range starts at or after 3, therefore -1. For i = 2, start = -3 and end = 3, so no range starts at or after 3, therefore -1. For i = 3, start = -50 and end = -20, so the ranges which start at or after -20 are range [-3,3], [-1,1] and [2,3] so the we will consider range with smallest starting point, therefore the answer is the range [-3,3] which is at index 2.
Approach: To solve the problem follow the below idea:
This problem can be solved using Binary Search. Firstly, we can declare a map, say indexes which stores the index of every starting point. Now for every range i we can use using binary search to find the index of the range which has least starting point after the ending of i. If there is no range then the answer will be -1
Follow the steps mentioned below to implement the idea:
- Declare an array result[] to store the final answer.
- Declare a map indexes to store the index of every starting point.
- Iterate over all the ranges and find the lowerbound for ending of ith range in indexes.
- If we find a range, then store its index at result[i]
- Else store -1 at result[i]
- Return result
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int >
findNextOptimalRange(vector<vector< int > >& ranges)
{
map< int , int > indexes;
vector< int > result;
for ( int i = 0; i < ranges.size(); i++) {
int start = ranges[i][0];
indexes[start] = i;
}
for (vector< int > range : ranges) {
auto nextOptimalRange
= indexes.lower_bound(range[1]);
if (nextOptimalRange != indexes.end()) {
int index = (*nextOptimalRange).second;
result.push_back(index);
}
else
result.push_back(-1);
}
return result;
}
int main()
{
vector<vector< int > > ranges{
{ -1, 1 }, { 2, 3 }, { -3, 3 }, { -50, -20 }
};
vector<vector< int > > ranges1{ { -1, -1 },
{ -2, 3 },
{ 3, 3 } };
vector< int > result = findNextOptimalRange(ranges1);
for ( int i : result) {
cout << i << " ";
}
return 0;
}
|
Java
import java.util.*;
public class GFG {
public static List<Integer> findNextOptimalRange(
List<Map.Entry<Integer, Integer> > ranges)
{
Map<Integer, Integer> indexes = new TreeMap<>();
List<Integer> result = new ArrayList<>();
for ( int i = 0 ; i < ranges.size(); i++) {
int start = ranges.get(i).getKey();
indexes.put(start, i);
}
for (Map.Entry<Integer, Integer> range1 : ranges) {
Integer nextOptimalRange = null ;
for ( int key : indexes.keySet()) {
if (key > range1.getValue()) {
nextOptimalRange = indexes.get(key);
break ;
}
}
if (nextOptimalRange != null ) {
result.add(nextOptimalRange);
}
else {
result.add(- 1 );
}
}
return result;
}
public static void main(String[] args)
{
List<Map.Entry<Integer, Integer> > ranges
= new ArrayList<>();
ranges.add(Map.entry(- 1 , 1 ));
ranges.add(Map.entry( 2 , 3 ));
ranges.add(Map.entry(- 3 , 3 ));
ranges.add(Map.entry(- 50 , - 20 ));
List<Integer> result = findNextOptimalRange(ranges);
for ( int i : result) {
System.out.print(i + " " );
}
}
}
|
Python3
def find_next_optimal_range(ranges):
indexes = {}
result = []
for i in range ( len (ranges)):
start = ranges[i][ 0 ]
indexes[start] = i
for range1 in ranges:
next_optimal_range = None
for key in sorted (indexes.keys()):
if key > range1[ 1 ]:
next_optimal_range = indexes[key]
break
if next_optimal_range is not None :
result.append(next_optimal_range)
else :
result.append( - 1 )
return result
ranges = [( - 1 , 1 ), ( 2 , 3 ), ( - 3 , 3 ), ( - 50 , - 20 )]
ranges1 = [( - 1 , - 1 ), ( - 2 , 3 ), ( 3 , 3 )]
result = find_next_optimal_range(ranges)
for i in result:
print (i, end = " " )
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG
{
public static List< int > FindNextOptimalRange(List<Tuple< int , int >> ranges)
{
Dictionary< int , int > indexes = new Dictionary< int , int >();
List< int > result = new List< int >();
for ( int i = 0; i < ranges.Count; i++)
{
int start = ranges[i].Item1;
indexes[start] = i;
}
foreach ( var range1 in ranges)
{
int ? nextOptimalRange = null ;
foreach ( int key in indexes.Keys.OrderBy(k => k))
{
if (key > range1.Item2)
{
nextOptimalRange = indexes[key];
break ;
}
}
if (nextOptimalRange != null )
{
result.Add(nextOptimalRange.Value);
}
else
{
result.Add(-1);
}
}
return result;
}
public static void Main( string [] args)
{
List<Tuple< int , int >> ranges = new List<Tuple< int , int >> {
Tuple.Create(-1, 1),
Tuple.Create(2, 3),
Tuple.Create(-3, 3),
Tuple.Create(-50, -20)
};
List< int > result = FindNextOptimalRange(ranges);
foreach ( int i in result)
{
Console.Write(i + " " );
}
}
}
|
Javascript
function GFG(ranges) {
const indexes = {};
const result = [];
for (let i = 0; i < ranges.length; i++) {
const start = ranges[i][0];
indexes[start] = i;
}
for (const range1 of ranges) {
let nextOptimalRange = null ;
for (const key of Object.keys(indexes).sort((a, b) => a - b)) {
if (key > range1[1]) {
nextOptimalRange = indexes[key];
break ;
}
}
if (nextOptimalRange !== null ) {
result.push(nextOptimalRange);
} else {
result.push(-1);
}
}
return result;
}
const ranges = [[-1, 1], [2, 3], [-3, 3], [-50, -20]];
const ranges1 = [[-1, -1], [-2, 3], [3, 3]];
const result = GFG(ranges);
console.log(result.join( " " ));
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...