# Split the given ranges into two groups

Last Updated : 05 Apr, 2023

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 ` `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>& 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> 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> 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> ranges = ``new` `List> {` `      ``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)

Previous
Next