Open In App

Find if there exists a direction for ranges such that no two range intersect

Given N ranges [L, R] with velocities vel[]. The task is to assign each range a direction i.e. either left or right. All the ranges will start moving in the assigned direction at time t = 0. Find, if there is an assignment of directions possible given that no two ranges overlap at infinite time.
Examples: 

Input: range[][] = {{1, 2}, {2, 5}, {3, 10}, {4, 4}, {5, 7}}, 
vel[] = {3, 1, 1, 1, 10} 
Output: No 
Intervals {2, 5}, {3, 10} and {4, 4} share a common point 4 
and have the same velocity.
Input: range[][] = {{1, 2}, {2, 5}, {3, 10}, {4, 4}, {5, 7}}, 
vel[] = {3, 1, 11, 1, 10} 
Output: Yes 

Approach:  

Below is the implementation of the above approach:




// C++ implementation of the approach
#include <bits/stdc++.h>
#define MAX 100001
using namespace std;
 
// Structure to hold details of
// each interval
typedef struct
{
    int l, r, v;
} interval;
 
// Comparator to sort intervals
// based on velocity
bool cmp(interval a, interval b)
{
    return a.v < b.v;
}
 
// Function that returns true if the
// assignment of directions is possible
bool isPossible(int range[][3], int N)
{
    interval test[N];
    for (int i = 0; i < N; i++) {
        test[i].l = range[i][0];
        test[i].r = range[i][1];
        test[i].v = range[i][2];
    }
 
    // Sort the intervals based on velocity
    sort(test, test + N, cmp);
 
    for (int i = 0; i < N; i++) {
        int count[MAX] = { 0 };
        int current_velocity = test[i].v;
 
        int j = i;
 
        // Test the condition for all intervals
        // with same velocity
        while (j < N && test[j].v == current_velocity) {
            for (int k = test[j].l; k <= test[j].r; k++) {
                count[k]++;
 
                // If for any velocity, 3 or more intervals
                // share a common point return false
                if (count[k] >= 3)
                    return false;
            }
            j++;
        }
 
        i = j - 1;
    }
 
    return true;
}
 
// Driver code
int main()
{
    int range[][3] = { { 1, 2, 3 },
                       { 2, 5, 1 },
                       { 3, 10, 1 },
                       { 4, 4, 1 },
                       { 5, 7, 10 } };
    int n = sizeof(range) / sizeof(range[0]);
 
    if (isPossible(range, n))
        cout << "Yes";
    else
        cout << "No";
 
    return 0;
}




// Java implementation of the approach
import java.util.*;
 
class GFG
{
static int MAX = 100001;
 
// Structure to hold details of
// each interval
static class interval
{
    int l, r, v;
}
 
static class Sort implements Comparator<interval>
{
    // Comparator to sort intervals
    // based on velocity
    public int compare(interval a, interval b)
    {
        return (a.v < b.v ? 1 : 0);
    }
}
 
// Function that returns true if the
// assignment of directions is possible
static boolean isPossible(int range[][], int N)
{
    interval test[] = new interval[N];
    for (int i = 0; i < N; i++)
    {
        test[i] = new interval();
        test[i].l = range[i][0];
        test[i].r = range[i][1];
        test[i].v = range[i][2];
    }
 
    // Sort the intervals based on velocity
    Arrays.sort(test, new Sort());
 
    for (int i = 0; i < N; i++)
    {
        int count[] = new int[MAX];
        int current_velocity = test[i].v;
 
        int j = i;
 
        // Test the condition for all intervals
        // with same velocity
        while (j < N && test[j].v == current_velocity)
        {
            for (int k = test[j].l; k <= test[j].r; k++)
            {
                count[k]++;
 
                // If for any velocity, 3 or more intervals
                // share a common point return false
                if (count[k] >= 3)
                    return false;
            }
            j++;
        }
        i = j - 1;
    }
    return true;
}
 
// Driver code
public static void main(String args[])
{
    int range[][] = {{ 1, 2, 3 },
                     { 2, 5, 1 },
                     { 3, 10, 1 },
                     { 4, 4, 1 },
                     { 5, 7, 10 }};
    int n = range.length;
 
    if (isPossible(range, n))
        System.out.println("Yes");
    else
        System.out.println("No");
}
}
 
// This code is contributed by Arnab Kundu




# Python implementation of the approach
MAX = 100001
 
# Function that returns true if the
# assignment of directions is possible
def isPossible(range, N):
     
    # Structure to hold details of
    # each interval
    test = [[0 for x in range(3)] for x in range(N)]
    for i in range(N):
        test[i][0] = range[i][0]
        test[i][1] = range[i][1]
        test[i][2] = range[i][2]
         
    # Sort the intervals based on velocity
    test.sort(key = lambda x: x[2])
    for i in range(N):
        count = [0] * MAX
        current_velocity = test[i][2]
        j = i
         
        # Test the condition for all intervals
        # with same velocity
        while (j < N and test[j][2] == current_velocity):
            for k in range(test[j][0], test[j][1] + 1):
                count[k] += 1
                 
                # If for any velocity, 3 or more intervals
                # share a common poreturn false
                if (count[k] >= 3):
                    return False
            j += 1
        i = j - 1
     
    return True
     
# Driver code
range = [[1, 2, 3] ,[2, 5, 1] ,[3, 10, 1],
        [4, 4, 1 ],[5, 7, 10 ]]
n = len(range)
if (isPossible(range, n)):
    print("Yes")
else:
    print("No")
     
# This code is contributed by SHUBHAMSINGH10




// C# implementation of the approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG
{
     
// Structure to hold details of
// each interval
public class interval
{
    public int l, r, v;
}
 
     
public class sortHelper : IComparer<interval>
{
   public int Compare(interval a, interval b)
   {
      return (a.v < b.v ? 1 : 0);
   }
}
     
static int MAX = 100001;
 
// Function that returns true if the
// assignment of directions is possible
static bool isPossible(int [,]range, int N)
{
    interval []test = new interval[N];
    for (int i = 0; i < N; i++)
    {
        test[i] = new interval();
        test[i].l = range[i, 0];
        test[i].r = range[i, 1];
        test[i].v = range[i, 2];
    }
 
    // Sort the intervals based on velocity
    Array.Sort(test, new sortHelper());
 
    for (int i = 0; i < N; i++)
    {
        int []count = new int[MAX];
        int current_velocity = test[i].v;
 
        int j = i;
 
        // Test the condition for all intervals
        // with same velocity
        while (j < N && test[j].v == current_velocity)
        {
            for (int k = test[j].l; k <= test[j].r; k++)
            {
                count[k]++;
 
                // If for any velocity, 3 or more intervals
                // share a common point return false
                if (count[k] >= 3)
                    return false;
            }
            j++;
        }
        i = j - 1;
    }
    return true;
}
 
// Driver code
public static void Main(string []args)
{
    int [,]range = {{ 1, 2, 3 },
                     { 2, 5, 1 },
                     { 3, 10, 1 },
                     { 4, 4, 1 },
                     { 5, 7, 10 }};
                      
    int n = range.GetLength(0);
 
    if (isPossible(range, n))
        Console.WriteLine("Yes");
    else
        Console.WriteLine("No");
}
}
 
// This code is contributed by rutvik_56




<script>
// Javascript implementation of the approach
let MAX = 100001;
 
// Structure to hold details of
// each interval
class interval
{
    constructor()
    {
        this.l = this.r = this.v = 0;
    }
}
 
// Function that returns true if the
// assignment of directions is possible
function isPossible(range,N)
{
    let test = new Array(N);
    for (let i = 0; i < N; i++)
    {
        test[i] = new interval();
        test[i].l = range[i][0];
        test[i].r = range[i][1];
        test[i].v = range[i][2];
    }
  
    // Sort the intervals based on velocity
    test.sort(function(a,b){return (a.v < b.v ? 1 : 0);});
  
    for (let i = 0; i < N; i++)
    {
        let count = new Array(MAX);
        for(let i=0;i<MAX;i++)
            count[i]=0;
        let current_velocity = test[i].v;
  
        let j = i;
  
        // Test the condition for all intervals
        // with same velocity
        while (j < N && test[j].v == current_velocity)
        {
            for (let k = test[j].l; k <= test[j].r; k++)
            {
                count[k]++;
  
                // If for any velocity, 3 or more intervals
                // share a common point return false
                if (count[k] >= 3)
                    return false;
            }
            j++;
        }
        i = j - 1;
    }
    return true;
}
 
// Driver code
let range=[[ 1, 2, 3 ],
                     [ 2, 5, 1 ],
                     [ 3, 10, 1 ],
                     [ 4, 4, 1 ],
                     [ 5, 7, 10 ]]
let n = range.length;
 
if (isPossible(range, n))
    document.write("Yes<br>");
else
    document.write("No<br>");
 
// This code is contributed by unknown2108
</script>

Output: 
No

 

Time Complexity: O(N2*K) where N is the number of ranges and K is the largest range possible(i.e largest (R-L) value)
Auxiliary Space: O(1).


Article Tags :