Open In App

Split the given ranges into two groups

Last Updated : 05 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D array span[][] of length N which contains spans [L, R] (0 ≤ L ≤ R ≤ 109), the task is to merge those spans which are coinciding and after that split those spans into two groups.

Note: Return numbers of ways these spans can be split following the given condition. Since the answer may be very large, return it modulo 109 + 7.

Examples:

Input: span[][] = [[1, 3], [10, 20], [2, 5], [4, 8]], N = 4
Output: 4
Explanation: As span[0], span[2] and span[3] can be merged into S1: [1, 8] and S2: [10, 20] Now, there are 4 ways in which we can split S1 and S2 in two groups:

  • Case 1: group-1 contains (S1, S2) and group-2 is empty.
  • Case 2: group-1 contains (S1) and group-2 contains (S2).
  • Case 3: group-1 contains (S2) and group-2 contains (S1).
  • Case 4: group-1 is empty and group-2 contains (S1, S2).

Input: span[][] = [[6, 10], [5, 15]], N = 2
Output: 2
Explanation: As span[0] and span[1] can merged into S1: [5, 15] Now, there are 2 ways in which we can split S1 in two groups:

  • Case 1: group-1 contains (S1) and group-2 is empty.
  • Case 2: group-1 is empty and group-2 contains (S1).

Approach: To solve the problem follow the below idea:

  • Sort the given array span in non-decreasing order (on the basis of span[i][0]).
  • After sorting, iterate the array and count unique ranges which are non-coinciding.
  • We can find coinciding spans by comparing the last value of the last span and the first value of the current span, if it is smaller then, we can merge these two spans and update the last value.
  • Return number of ways for distributing n things into two groups is (2)n.

Below are the steps for the above approach:

  • Sort the given array span in non-decreasing order.
  • Initialize a variable say, uniqueRanges = 1 to count unique non-coinciding spans present in the given spans array.
  • Initialize a variable say, end = ranges[0][1].
  • Run a loop from i = 1 to i < N and check if it is coinciding, update the variable end
    • if (ranges[i][0] <= end), end = Math.max(end, ranges[i][1])
    • else, increment uniqueRanges and update variable end,
      • uniqueRanges++
      • end = ranges[i][1]
  • Return number of ways for distributing n things into two groups is (2)n,
    • return power(uniqueRanges)

Below is the code for the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
const int mod = 1e9+7;
 
int power(int num)
{
    if (num == 1)
        return 2;
    long long a = power(num / 2);
    int k = (a * a) % mod;
    if (num % 2 != 0) {
        return (k * 2LL) % mod;
    }
    return k;
}
 
int splittingWays(vector<vector<int>>& ranges)
{
    int N = ranges.size();
    // Sorting the given array
    sort(ranges.begin(), ranges.end(), [](const vector<int>& a, const vector<int>& b)
        {
            if (a[0] == b[0])
                return a[1] < b[1];
            else
                return a[0] < b[0];
        });
    // Counting unique non-overlapping
    // ranges present in the
    // given ranges array
    int uniqueRanges = 1;
    int end = ranges[0][1];
    for (int i = 1; i < N; i++) {
 
        // Checking whether it is
        // overlapping or not
        if (ranges[i][0] <= end) {
            end = max(end, ranges[i][1]);
        }
        else {
            uniqueRanges++;
            end = ranges[i][1];
        }
    }
 
    // Return 2^uniqueRanges
    return power(uniqueRanges);
}
 
int main()
{
    vector<vector<int>> ranges = { { 1, 3 }, { 10, 20 }, { 2, 5 }, { 4, 8 } };
    cout << "Number of ways = " << splittingWays(ranges) << endl;
    return 0;
}


Java




// Java code of the above approach
 
import java.util.*;
 
class GFG {
    public static int mod = 1000000007;
    public static int power(int num)
    {
        if (num == 1)
            return 2;
        long a = power(num / 2);
        int k = (int)(a * a) % mod;
        if (num % 2 != 0) {
            return (k * 2) % mod;
        }
        return k;
    }
 
    // Drivers code
    public static void main(String[] args)
    {
        int[][] ranges
            = { { 1, 3 }, { 10, 20 }, { 2, 5 }, { 4, 8 } };
        int N = ranges.length;
        System.out.println("Number of ways = "
                           + splittingWays(ranges, N));
    }
 
    public static int splittingWays(int[][] ranges, int N)
    {
 
        // Sorting the given array
        Arrays.sort(ranges,
                    (a, b)
                        -> (a[0] == b[0]) ? a[1] - b[1]
                                          : a[0] - b[0]);
        // Counting unique non-overlapping
        // ranges present in the
        // given ranges array
        int uniqueRanges = 1;
        int end = ranges[0][1];
        for (int i = 1; i < N; i++) {
 
            // Checking whether it is
            // overlapping or not
            if (ranges[i][0] <= end) {
                end = Math.max(end, ranges[i][1]);
            }
            else {
                uniqueRanges++;
                end = ranges[i][1];
            }
        }
 
        // Return 2^uniqueRanges
        return power(uniqueRanges);
    }
}


Python3




def power(num):
    mod = 1000000007
    if num == 1:
        return 2
    a = power(num // 2)
    k = (a * a) % mod
    if num % 2 != 0:
        return (k * 2) % mod
    return k
 
def splittingWays(ranges, N):
    # Sorting the given array
    ranges.sort(key = lambda x: (x[0], x[1]))
 
    # Counting unique non-overlapping
    # ranges present in the
    # given ranges array
    uniqueRanges = 1
    end = ranges[0][1]
    for i in range(1, N):
        # Checking whether it is
        # overlapping or not
        if ranges[i][0] <= end:
            end = max(end, ranges[i][1])
        else:
            uniqueRanges += 1
            end = ranges[i][1]
 
    # Return 2^uniqueRanges
    return power(uniqueRanges)
 
ranges = [ [ 1, 3 ], [ 10, 20 ], [ 2, 5 ], [ 4, 8 ] ]
N = len(ranges)
print("Number of ways = ", splittingWays(ranges, N))
 
# Contributed by adityasha4x71


C#




using System;
using System.Collections.Generic;
 
public class Program
{
  const int mod = 1000000007;
 
  static int Power(int num)
  {
    if (num == 1)
      return 2;
    long a = Power(num / 2);
    int k = (int)((a * a) % mod);
    if (num % 2 != 0)
    {
      return (int)((k * 2L) % mod);
    }
    return k;
  }
 
  static int SplittingWays(List<List<int>> ranges)
  {
    int N = ranges.Count;
    // Sorting the given array
    ranges.Sort((a, b) =>
                {
                  if (a[0] == b[0])
                    return a[1].CompareTo(b[1]);
                  else
                    return a[0].CompareTo(b[0]);
                });
 
    // Counting unique non-overlapping
    // ranges present in the
    // given ranges array
    int uniqueRanges = 1;
    int end = ranges[0][1];
    for (int i = 1; i < N; i++)
    {
      // Checking whether it is
      // overlapping or not
      if (ranges[i][0] <= end)
      {
        end = Math.Max(end, ranges[i][1]);
      }
      else
      {
        uniqueRanges++;
        end = ranges[i][1];
      }
    }
 
    // Return 2^uniqueRanges
    return Power(uniqueRanges);
  }
 
  public static void Main()
  {
    List<List<int>> ranges = new List<List<int>> {
      new List<int> {1, 3},
      new List<int> {10, 20},
      new List<int> {2, 5},
      new List<int> {4, 8}
    };
    Console.WriteLine($"Number of ways = {SplittingWays(ranges)}");
  }
}


Javascript




const mod = 1e9 + 7;
 
function power(num) {
  if (num === 1) {
    return 2;
  }
  const a = power(Math.floor(num / 2));
  const k = (a * a) % mod;
  if (num % 2 !== 0) {
    return (k * 2n) % BigInt(mod);
  }
  return k;
}
 
function splittingWays(ranges) {
  const N = ranges.length;
  // Sorting the given array
  ranges.sort((a, b) => {
    if (a[0] === b[0]) {
      return a[1] - b[1];
    } else {
      return a[0] - b[0];
    }
  });
  // Counting unique non-overlapping
  // ranges present in the
  // given ranges array
  let uniqueRanges = 1;
  let end = ranges[0][1];
  for (let i = 1; i < N; i++) {
    // Checking whether it is
    // overlapping or not
    if (ranges[i][0] <= end) {
      end = Math.max(end, ranges[i][1]);
    } else {
      uniqueRanges++;
      end = ranges[i][1];
    }
  }
 
  // Return 2^uniqueRanges
  return power(uniqueRanges);
}
 
const ranges = [
  [1, 3],
  [10, 20],
  [2, 5],
  [4, 8]
];
console.log(`Number of ways = ${splittingWays(ranges)}`);


Output

Number of ways = 4

Time Complexity: O(N * log(N))
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads