Skip to content
Related Articles

Related Articles

Improve Article

Divide N segments into two non-empty groups such that given condition is satisfied

  • Difficulty Level : Medium
  • Last Updated : 09 Oct, 2021

Given N segments (or ranges) represented by two non-negative integers L and R. Divide these segments into two non-empty groups such that there are no two segments from different groups that share a common point. If it is possible to do so, assign each segment a number from the set {1, 2} otherwise print Not Possible.
Examples: 
 

Input: arr[][] = {{5, 5}, {2, 3}, {3, 4}} 
Output: 2 1 1 
Since 2nd and 3rd segment have one point common i.e. 3, they should be contained in same group.
Input: arr[][] = {{3, 5}, {2, 3}, {1, 4}} 
Output: Not Possible 
All segments should be contained in the same group since every pair has a common point with each other. Since the other group is empty, answer is not possible. 
 

Prerequisites: Merge Overlapping Intervals
 

Approach: Using the concept of merging overlapping intervals, we can assign the same group to all those segments that are overlapping and alternatively changing the group number. 
To merge overlapping segments, sort all the segments with respect to their increasing left values, if left values are equal, sort it on the basis of right values first keeping an order of the original indices of the segments. Then, iterate over the segments and check if any of the previous segments is overlapping with the current segment. If it does then merge it making it one segment and if it doesn’t create a new one. 
At last, check if one of the group is empty of not. If one of them is empty, answer is not possible, otherwise print all the assigned values of segments.
Below is the implementation of the above approach:
 

C++




// C++ Program to divide N segments
// into two non empty groups such that
// given condition is satisfied
 
#include<bits/stdc++.h>
using namespace std;
   
// Function to print the answer if
// it exists using the concept of
// merge overlapping segments
void printAnswer(vector<pair<int,int>> v,int n)
{
      // vec[i].first -> left value
      // vec[i].second.first -> right value
      // vec[i].second.second -> position
    vector<pair<int,pair<int,int>>> vec;
    for(int i=0;i<n;i++)
    {
        vec.push_back({v[i].first,{v[i].second,i}});
    }
    sort(vec.begin(),vec.end());
     
 // Resultant array
 //   Initialise all the values in resultant array with '2'
 //   except the position at the first index of sorted vec which is initialised as '1'
 //   Initialise maxR to store the maximum of all right values encountered so far
    vector<int> res(n,2);
    int maxR = vec[0].second.first;
    res[vec[0].second.second] = 1;
 
// If the i-th index has any any point in common with the (i-1)th index classify it as '1'
//    in resultant array and update maxR if necessary
// else we have found the breakpoint and we can exit the loop
     
    bool ok=false;
    for(int i=1;i<n;i++)
    {
        if(maxR>=vec[i].first)
        {
            res[vec[i].second.second] = res[vec[i-1].second.second];
            maxR=max(maxR,vec[i].second.first);
        }
        else
            {
                ok=true;
                break;
            }
    }
    if(ok)
    {
        for(auto x:res)
            cout << x << " ";
        cout << '\n';
    }
    else
        cout << "Not possible\n";
     
}
 
int main()
{
    vector<pair<int,int>> v = {{2,8}, {3,4} , {5,8}, {9,10}};
    int n = (int)v.size();
     
    printAnswer(v,n);
}

Python3




# Python3 Program to divide N segments
# into two non empty groups such that
# given condition is satisfied
     
# Function to print the answer if
# it exists using the concept of
# merge overlapping segments
 
def printAnswer(v, n):
    # Sort the indices based on their corresponding value in V   
    indices = list(range(n))
    indices.sort(key=lambda i: v[i])
     
    # Resultant array
    # Initialise all the values in resultant array with '2'
    # except the first index of 'indices' which is initialised as '1'
    # Initialise maxR to store the maximum of all right values encountered so far
    res = [2] * n
    res[indices[0]] = 1
    maxR=v[indices[0]][1]
     
    #If the i-th index has any any point in common with the (i-1)th index classify it as '1' in resultant array and update maxR if necessary
    #else we have found the breakpoint and we can exit the loop   
    for i in range(1, n):
        if maxR>=v[indices[i]][0]:
            res[indices[i]]=res[indices[i-1]]
            maxR=max(maxR,v[indices[i]][1])
        else:
            break
    else:
        print("Not possible")
        return
    print(" ".join(map(str,res)))
     
# Driver Code
if __name__ == "__main__":
 
    v = [[2, 8], [3, 4], [5, 8], [9, 10]]
    n = len(v)
    printAnswer(v, n)
Output
1 1 1 2 

Time Complexity: O(n * log n), where n is the number of segments
Auxiliary Space: O(n).  
 




My Personal Notes arrow_drop_up
Recommended Articles
Page :