Find k-th smallest element in given n ranges

Given n and q, i.e, the number of ranges and number of queries, find the kth smallest element for each query (assume k>1).Print the value of kth smallest element if it exists, else print -1.

Examples :

Input : arr[] = {{1, 4}, {6, 8}}
        queries[] = {2, 6, 10};
Output : 2
         7
        -1
After combining the given ranges, the numbers
become 1 2 3 4 6 7 8. As here 2nd element is 2,
so we print 2. As 6th element is 7, so we print
7 and as 10th element doesn't exist, so we
print -1.

Input : arr[] = {{2, 6}, {5, 7}}
        queries[] = {5, 8};
Output : 6
        -1
After combining the given ranges, the numbers 
become 2 3 4 5 6 7. As here 5th element is 6, 
so we print 6 and as 8th element doesn't exist, 
so we print -1.



The idea is to first Prerequisite : Merge Overlapping Intervals and keep all intervals sorted in ascending order of start time. After merging in an array merged[], we use linear search to find kth smallest element. Below is the implementation of the above approach :

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to solve k queries
// for given n ranges
#include <bits/stdc++.h>
using namespace std;
  
// Structure to store the
// start and end point
struct Interval
{
    int s;
    int e;
};
  
// Comparison function for sorting
bool comp(Interval a, Interval b)
{
    return a.s < b.s;
}
  
// Function to find Kth smallest number in a vector
// of merged intervals
int kthSmallestNum(vector<Interval> merged, int k)
{
    int n = merged.size();
  
    // Traverse merged[] to find
    // Kth smallest element using Linear search.
    for (int j = 0; j < n; j++)
    {
        if (k <= abs(merged[j].e -
                     merged[j].s + 1))
            return (merged[j].s + k - 1);
  
        k = k - abs(merged[j].e -
                     merged[j].s + 1);
    }
  
    if (k)
        return -1;
}
  
// To combined both type of ranges,
// overlapping as well as non-overlapping.
void mergeIntervals(vector<Interval> &merged,
                 Interval arr[], int n)
{
    // Sorting intervals according to start
    // time
    sort(arr, arr + n, comp);
  
    // Merging all intervals into merged
    merged.push_back(arr[0]);
    for (int i = 1; i < n; i++)
    {
        // To check if starting point of next
        // range is lying between the previous
        // range and ending point of next range
        // is greater than the Ending point
        // of previous range then update ending
        // point of previous range by ending
        // point of next range.
        Interval prev = merged.back();
        Interval curr = arr[i];
        if ((curr.s >= prev.s &&
             curr.s <= prev.e) &&
            (curr.e > prev.e))
  
            merged.back().e = curr.e;
  
        else
        {
            // If starting point of next range
            // is greater than the ending point
            // of previous range then store next range
            // in merged[].
            if (curr.s > prev.e)
                merged.push_back(curr);
        }
    }
}
  
// Driver\'s Function
int main()
{
    Interval arr[] = {{2, 6}, {4, 7}};
    int n = sizeof(arr)/sizeof(arr[0]);
    int query[] = {5, 8};
    int q = sizeof(query)/sizeof(query[0]);
  
    // Merge all intervals into merged[]
    vector<Interval>merged;
    mergeIntervals(merged, arr, n);
  
    // Processing all queries on merged
    // intervals
    for (int i = 0; i < q; i++)
        cout << kthSmallestNum(merged, query[i])
             << endl;
  
    return 0;
}

chevron_right


Output:

 6
 -1

Time Complexity : O(nlog(n))



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.