Find the missing elements from 1 to M in given N ranges | Set-2

Given an integer m and n ranges (e.g. [a, b]) which are intersecting and overlapping. The task is to find all the number within the range that doesn’t belong to any of the given ranges.

Examples: 

Input: m = 6, ranges = {{1, 2}, {4, 5}} 
Output: 3 6 
As only 3 and 6 are missing from the given ranges.

Input: m = 5, ranges = {{2, 4}} 
Output: 1 5  

Approach 1: As we have n ranges, if ranges are non-overlapping and non-intersecting then follow the approach described here
But here are overlapping and intersecting ranges, so first merge all the ranges so that there are no overlapping or intersecting ranges. 
After merging is done, iterate from each range and find the numbers which are missing.



Below is the implementation of the above approach:

Time Complexity: O(nlogn)

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
 
// function to find the missing
// numbers from the given ranges
void findNumbers(vector<pair<int, int> > ranges, int m)
{
    vector<int> ans;
 
    // prev is use to store end of last range
    int prev = 0;
 
    // j is used as counter for range
    for (int j = 0; j < ranges.size(); j++) {
        int start = ranges[j].first;
        int end = ranges[j].second;
        for (int i = prev + 1; i < start; i++)
            ans.push_back(i);
        prev = end;
    }
 
    // for last range
    for (int i = prev + 1; i <= m; i++)
        ans.push_back(i);
 
    // finally print all answer
    for (int i = 0; i < ans.size(); i++)
        if (ans[i] <= m)
            cout << ans[i] << " ";
}
 
// function to return the ranges after merging
vector<pair<int, int> > mergeRanges(
    vector<pair<int, int> > ranges, int m)
{
    // sort all the ranges
    sort(ranges.begin(), ranges.end());
    vector<pair<int, int> > ans;
 
    ll prevFirst = ranges[0].first,
       prevLast = ranges[0].second;
 
    // merging of overlapping ranges
    for (int i = 0; i < m; i++) {
        ll start = ranges[i].first;
        ll last = ranges[i].second;
 
        // ranges do not overlap
        if (start > prevLast) {
            ans.push_back({ prevFirst, prevLast });
            prevFirst = ranges[i].first;
            prevLast = ranges[i].second;
        }
        else
            prevLast = last;
 
        if (i == m - 1)
            ans.push_back({ prevFirst, prevLast });
    }
    return ans;
}
 
// Driver code
int main()
{
    // vector of pair to store the ranges
    vector<pair<int, int> > ranges;
    ranges.push_back({ 1, 2 });
    ranges.push_back({ 4, 5 });
 
    int n = ranges.size();
    int m = 6;
 
    // this function returns merged ranges
    vector<pair<int, int> > mergedRanges
        = mergeRanges(ranges, n);
 
    // this function is use to find
    // missing numbers upto m
    findNumbers(mergedRanges, m);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
 
class GFG{
 
static class Pair
{
    int first, second;
 
    public Pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
// Function to find the missing
// numbers from the given ranges
static void findNumbers(ArrayList<Pair> ranges,
                        int m)
{
    ArrayList<Integer> ans = new ArrayList<>();
 
    // prev is use to store end of last range
    int prev = 0;
 
    // j is used as counter for range
    for(int j = 0; j < ranges.size(); j++)
    {
        int start = ranges.get(j).first;
        int end = ranges.get(j).second;
         
        for(int i = prev + 1; i < start; i++)
            ans.add(i);
             
        prev = end;
    }
 
    // For last range
    for(int i = prev + 1; i <= m; i++)
        ans.add(i);
 
    // Finally print all answer
    for(int i = 0; i < ans.size(); i++)
        if (ans.get(i) <= m)
            System.out.print(ans.get(i) + " ");
}
 
// Function to return the ranges after merging
static ArrayList<Pair> mergeRanges(ArrayList<Pair> ranges,
                                   int m)
{
     
    // Sort all the ranges
    Collections.sort(ranges, new Comparator<Pair>()
    {
        public int compare(Pair first, Pair second)
        {
            if (first.first == second.first)
            {
                return first.second - second.second;
            }
            return first.first - second.first;
        }
    });
 
    ArrayList<Pair> ans = new ArrayList<>();
 
    int prevFirst = ranges.get(0).first,
         prevLast = ranges.get(0).second;
 
    // Merging of overlapping ranges
    for(int i = 0; i < m; i++)
    {
        int start = ranges.get(i).first;
        int last = ranges.get(i).second;
 
        // Ranges do not overlap
        if (start > prevLast)
        {
            ans.add(new Pair(prevFirst, prevLast));
            prevFirst = ranges.get(i).first;
            prevLast = ranges.get(i).second;
        }
        else
            prevLast = last;
 
        if (i == m - 1)
            ans.add(new Pair(prevFirst, prevLast));
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
     
    // Vector of pair to store the ranges
    ArrayList<Pair> ranges = new ArrayList<>();
    ranges.add(new Pair(1, 2));
    ranges.add(new Pair(4, 5));
 
    int n = ranges.size();
    int m = 6;
 
    // This function returns merged ranges
    ArrayList<Pair> mergedRanges = mergeRanges(ranges, n);
     
    // This function is use to find
    // missing numbers upto m
    findNumbers(mergedRanges, m);
}
}
 
// This code is contributed by sanjeev2552
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
 
# function to find the missing
# numbers from the given ranges
def findNumbers(ranges, m):
 
    ans = []
  
    # prev is use to store
    # end of last range
    prev = 0
  
    # j is used as counter for range
    for j in range(len(ranges)):
        start = ranges[j][0]
        end = ranges[j][1]
         
        for i in range(prev + 1, start):
            ans.append(i)
             
        prev = end
  
    # For last range
    for i in range(prev + 1, m + 1):
            ans.append(i)
  
    # Finally print all answer
    for i in range(len(ans)):
        if (ans[i] <= m):
            print(ans[i], end = ' ')
 
# Function to return the ranges
# after merging
def mergeRanges(ranges, m):
     
    # sort all the ranges
    ranges.sort()
    ans = []
  
    prevFirst = ranges[0][0]
    prevLast = ranges[0][1]
  
    # Merging of overlapping ranges
    for i in range(m):
        start = ranges[i][0]
        last = ranges[i][1]
     
        # Ranges do not overlap
        if (start > prevLast):
            ans.append([prevFirst, prevLast])
            prevFirst = ranges[i][0]
            prevLast = ranges[i][1]
        else:
            prevLast = last;
  
        if (i == m - 1):
            ans.append([prevFirst, prevLast])
     
    return ans
 
# Driver code
if __name__=="__main__":
     
    # Vector of pair to store the ranges
    ranges = []
    ranges.append([ 1, 2 ]);
    ranges.append([ 4, 5 ]);
  
    n = len(ranges)
    m = 6
  
    # This function returns merged ranges
    mergedRanges = mergeRanges(ranges, n);
  
    # This function is use to find
    # missing numbers upto m
    findNumbers(mergedRanges, m);
 
# This code is contributed by rutvik_56
chevron_right

Output: 
3 6

 

Approach 2:

Make an Array of size m and initialized with zero. For every range {L,R} do array[L]++ and array[R+1]– . Now iterate through the array while taking sum, if sum = x at index i this indicates that number i comes under in sum ranges, for example, if at index 2 that value of sum = 3 it means that number 2 comes under 3 ranges. so when the sum is 0 that indicates the given number does not come under any of the given ranges, Print these numbers

Given below is the implementation of the above Approach 2.

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// function to find the missing
// numbers from the given ranges
void findNumbers(vector<pair<int, int> > ranges, int m)
{
     
    //Intialized the array of size m+1 with zero
    int r[m+1];
    memset(r,0,sizeof(int)*(m+1));
     
    //for each range [L,R] do array[L]++ and array[R+1]--
    for(int i=0;i<ranges.size();i++)
    {
        if(ranges[i].first<=m)
            r[ranges[i].first]++;//array[L]++
             
        if(ranges[i].second+1<=m)
            r[ranges[i].second+1]--;//array[R+1]--
    }
     
    // Now iterate array and take the sum
    // if sum = x i.e, that particular number
    // comes under x ranges
    // thats means if sum = 0 so that number does not
    // include in any of ranges(print these numbers)
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        sum+=r[i];
        if(sum==0){
            cout<<i<<" ";
        }
    }
}
// Driver Code
int main() {
   
    // vector of pair to store the ranges
    vector<pair<int, int> > ranges;
    ranges.push_back({ 1, 2 });
    ranges.push_back({ 4, 5 });
 
    int n = ranges.size();
    int m = 6;
   
    // this function is use to find
    // missing numbers upto m
    findNumbers(ranges, m);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of
# the above approach
 
# Function to find the missing
# numbers from the given ranges
def findNumbers(ranges, m):
     
    # Intialized the array
    # of size m+1 with zero
    r = [0] * (m + 1)
    
    # For each range [L,R] do
    # array[L]++ and array[R+1]--
    for i in range (len(ranges)):
     
        if(ranges[i][0] <= m):
         
            # array[L]++
            r[ranges[i][0]] += 1
             
        if(ranges[i][1] + 1 <= m):
           
             # array[R+1]--
            r[ranges[i][1] + 1] -= 1
    
    # Now iterate array and
    # take the sum if sum = x
    # i.e, that particular number
    # comes under x ranges
    # thats means if sum = 0 so
    # that number does not include
    # in any of ranges(print these numbers)
    sum = 0
     
    for i in range(1, m + 1):  
        sum += r[i]
        if(sum == 0):
            print(i, end = " ")
     
# Driver Code
if __name__ == "__main__":
   
    # Vector of pair to
    # store the ranges
    ranges = []
    ranges.append([1, 2])
    ranges.append([4, 5])
 
    n = len(ranges)
    m = 6
   
    # This function is use
    # to find missing numbers
    # upto m
    findNumbers(ranges, m)
 
# This code is contributed by Chitranayal
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections;
using System.Collections.Generic;
  
class GFG
{
     
// function to find the missing
// numbers from the given ranges
static void findNumbers(ArrayList ranges, int m)
{
      
    // Intialized the array of size m+1 with zero
    int []r = new int[m + 1];
    Array.Fill(r, 0);
      
    // for each range [L,R] do array[L]++ and array[R+1]--
    for(int i = 0; i < ranges.Count; i++)
    {
        if(((KeyValuePair<int, int>)ranges[i]).Key <= m)
            r[((KeyValuePair<int, int>)ranges[i]).Key]++;// array[L]++
              
        if(((KeyValuePair<int, int>)ranges[i]).Value + 1 <= m)
            r[((KeyValuePair<int, int>)ranges[i]).Value + 1]--;// array[R+1]--
    }
      
    // Now iterate array and take the sum
    // if sum = x i.e, that particular number
    // comes under x ranges
    // thats means if sum = 0 so that number does not
    // include in any of ranges(print these numbers)
    int sum = 0;
    for(int i = 1; i <= m; i++)
    {
        sum += r[i];
        if(sum == 0)
        {
            Console.Write(i + " ");
        }
    }
}
   
// Driver Code
static void Main(string []arg)
{
    
    // vector of pair to store the ranges
    ArrayList ranges = new ArrayList();
      
    ranges.Add(new KeyValuePair<int,int>(1, 2));
    ranges.Add(new KeyValuePair<int,int>(4, 5));
  
    int n = ranges.Count;
    int m = 6;
    
    // this function is use to find
    // missing numbers upto m
    findNumbers(ranges, m);
}
}
 
// This code is contributed by pratham76
chevron_right

Output: 
3 6

 

Time Complexity: O(n)




Recommended Posts:

    Article Tags :
    Practice Tags :