Find the kth element in the series generated by the given N ranges in C++


In this problem, we are given a N range of integer values between intervals L - R as an matrix range[N][2] and an integer value k. Our task is to find the kth element in the series generated by the given N ranges.

Let's take an example to understand the problem,

Input : ranges[][] = {{1, 3}, {5, 7}}, k = 4
Output : 5

Explanation

The series is {1, 2, 3, 5, 6, 7}
The 4th element is 5.

Solution Approach

A simple solution to the problem is by creating a series of integers for the given ranges and then find the elements at index k of their array.

Example

Program to illustrate the working of our solution

#include <iostream>
using namespace std;
int findKthSmallestEleSeries(int n, int k, int range[][2]){
   int rangeVal[10000];
   int rangeSize = 0;
   for(int i = 0; i < n; i++){
      for(int j = range[i][0]; j <= range[i][1]; j++){
         rangeVal[rangeSize] = j;
         rangeSize++;
      }
   }
   return rangeVal[k-1];
}
int main(){
   int L[] = { 1, 5 };
   int R[] = { 3, 8 };
   int range[][2] = {{1, 3}, {5, 8}};
   int n = sizeof(L) / sizeof(int);
   int k = 4;
   cout<<k<<"-th element of the series generated by ranges is "<<
   findKthSmallestEleSeries(n, k, range); 
   return 0;
}

Output

4-th element of the series generated by ranges is 5

This method is good but can lead to memory issues if the ranges are too large. Hence, we need to derive a better approach that storing all elements of the array.

Another approach

Another approach to solve the problem is by using binary search and counter array. The counter array will store the count of integers till the given range, count[i] = count of character till i-th range.

Then for k, we will find the range number i, in which the k-th smallest value lies.

Then we will find the value in this range.

Example

Program to illustrate the working of our solution

#include <iostream>
using namespace std;
int findKthSmallestEleSeries(int n, int k, int range[][2]){
   int start = 1;
   int end = n;
   int count[n + 1];
   count[0] = 0;
   for (int i = 0; i < n; i++)
      count[i + 1] = count[i] + (range[i][1] - range[i][0]) + 1;
   int index = -1;
   int mid;
   while (start <= end) {
      mid = (start + end) / 2;
      if (count[mid] > k) {
         index = mid;
         end = mid - 1;
      }
      else if (count[mid] < k) 
         start = mid + 1;
      else {
         index = mid;
         break;
      }
   }
   start = range[index - 1][0];
   end = range[index - 1][1];
   int indexK = k - count[index - 1];
   while (start <= end) {
      mid = (start + end) / 2;
      if ((mid - range[index - 1][0]) + 1 == indexK) {
         return mid;
      }
      else if ((mid - range[index - 1][0]) + 1 > indexK)
         end = mid - 1;
      else
         start = mid + 1;
   }
   return -1;
}
int main(){
   int L[] = { 1, 5 };
   int R[] = { 3, 8 };
   int range[][2] = {{1, 3}, {5, 8}};
   int n = sizeof(L) / sizeof(int);
   int k = 4;
   cout<<k<<"-th element of the series generated by ranges is "<<
   findKthSmallestEleSeries(n, k, range);
   return 0;
}

Output

4-th element of the series generated by ranges is 5

Updated on: 28-Jan-2022

185 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements