Given K sorted lists of integers of size N each, find the smallest range that includes at least one element from each of the K lists. If more than one smallest range is found, print any one of them.
Examples:
Input: K = 3
arr1[] : {4, 7, 9, 12, 15}
arr2[] : {0, 8, 10, 14, 20}
arr3[] : {6, 12, 16, 30, 50}Output: The smallest range is [6 8]
Explanation: Smallest range is formed by number 7 from the first list, 8 from second list and 6 from the third list.Input: k = 3
arr1[] : {4, 7}
arr2[] : {1, 2}
arr3[] : {20, 40}Output: The smallest range is [2 20]
Explanation:The range [2, 20] contains 2, 4, 7, 20 which contains element from all the three arrays.
Naive Approach:
The idea is to keep k pointers which will constitute the elements in the range, by taking the min and max of the K elements the range can be formed. Initially, all the pointers will point to the start of all the K arrays. Store the range max to min. If the range has to be minimized then either the minimum value has to be increased or the maximum value has to be decreased. To decrease the maximum value we have to move our pointer of current maximum to the left and since we are currently at 0 the index of every list so we can’t move our pointer to left, hence we can’t decrease the current max. So, the only possible option to get a better range is to increase the current minimum. To continue increasing the minimum value, increase the pointer of the list containing the minimum value and update the range until one of the lists exhausts.
Follow the given steps to solve the problem:
- Create an extra space ptr of length K to store the pointers and a variable minrange initialized to a maximum value.
- Initially, the index of every list is 0, therefore initialize every element of ptr[0..k] to 0, and the array ptr will store the index of the elements in the range.
-
Repeat the following steps until at least one list exhausts:
- Now find the minimum and maximum value among the current elements of all the lists pointed by the ptr[0…k] array.
- Update the minrange if the current (max-min) is less than minrange.
- increment the pointer pointing to the current minimum element.
Below is the Implementation of the above approach:
// C++ program to finds out smallest range that includes // elements from each of the given sorted lists. #include <bits/stdc++.h> using namespace std;
// array for storing the current index of list i int ptr[501];
// This function takes an k sorted lists in the form of // 2D array as an argument. It finds out smallest range // that includes elements from each of the k lists. void findSmallestRange(vector<vector< int > >& arr, int N,
int K)
{ int i, minval, maxval, minrange, minel, maxel, flag,
minind;
// initializing to 0 index;
for (i = 0; i <= K; i++)
ptr[i] = 0;
minrange = INT_MAX;
while (1) {
// for maintaining the index of list containing the
// minimum element
minind = -1;
minval = INT_MAX;
maxval = INT_MIN;
flag = 0;
// iterating over all the list
for (i = 0; i < K; i++) {
// if every element of list[i] is traversed then
// break the loop
if (ptr[i] == N) {
flag = 1;
break ;
}
// find minimum value among all the list
// elements pointing by the ptr[] array
if (ptr[i] < N && arr[i][ptr[i]] < minval) {
minind = i; // update the index of the list
minval = arr[i][ptr[i]];
}
// find maximum value among all the list
// elements pointing by the ptr[] array
if (ptr[i] < N && arr[i][ptr[i]] > maxval) {
maxval = arr[i][ptr[i]];
}
}
// if any list exhaust we will not get any better
// answer, so break the while loop
if (flag)
break ;
ptr[minind]++;
// updating the minrange
if ((maxval - minval) < minrange) {
minel = minval;
maxel = maxval;
minrange = maxel - minel;
}
}
printf ( "The smallest range is [%d, %d]\n" , minel,
maxel);
} // Driver's code int main()
{ vector<vector< int > > arr = { { 4, 7, 9, 12, 15 },
{ 0, 8, 10, 14, 20 },
{ 6, 12, 16, 30, 50 } };
int K = arr.size();
int N = arr[0].size();
// Function call
findSmallestRange(arr, N, K);
return 0;
} // This code is contributed by Aditya Krishna Namdeo |
// Java program to finds out smallest range that includes // elements from each of the given sorted lists. class GFG {
static final int N = 5 ;
// array for storing the current index of list i
static int ptr[] = new int [ 501 ];
// This function takes an k sorted lists in the form of
// 2D array as an argument. It finds out smallest range
// that includes elements from each of the k lists.
static void findSmallestRange( int arr[][], int n, int k)
{
int i, minval, maxval, minrange,
minel = 0 , maxel = 0 , flag, minind;
// initializing to 0 index;
for (i = 0 ; i <= k; i++) {
ptr[i] = 0 ;
}
minrange = Integer.MAX_VALUE;
while ( true ) {
// for maintaining the index of list containing
// the minimum element
minind = - 1 ;
minval = Integer.MAX_VALUE;
maxval = Integer.MIN_VALUE;
flag = 0 ;
// iterating over all the list
for (i = 0 ; i < k; i++) {
// if every element of list[i] is traversed
// then break the loop
if (ptr[i] == n) {
flag = 1 ;
break ;
}
// find minimum value among all the list
// elements pointing by the ptr[] array
if (ptr[i] < n && arr[i][ptr[i]] < minval) {
minind
= i; // update the index of the list
minval = arr[i][ptr[i]];
}
// find maximum value among all the list
// elements pointing by the ptr[] array
if (ptr[i] < n && arr[i][ptr[i]] > maxval) {
maxval = arr[i][ptr[i]];
}
}
// if any list exhaust we will not get any
// better answer, so break the while loop
if (flag == 1 ) {
break ;
}
ptr[minind]++;
// updating the minrange
if ((maxval - minval) < minrange) {
minel = minval;
maxel = maxval;
minrange = maxel - minel;
}
}
System.out.printf(
"The smallest range is [%d, %d]\n" , minel,
maxel);
}
// Driver program to test above function
public static void main(String[] args)
{
int arr[][] = { { 4 , 7 , 9 , 12 , 15 },
{ 0 , 8 , 10 , 14 , 20 },
{ 6 , 12 , 16 , 30 , 50 } };
int k = arr.length;
findSmallestRange(arr, N, k);
}
} // this code contributed by Rajput-Ji |
# Python3 program to finds out # smallest range that includes # elements from each of the # given sorted lists. N = 5
# array for storing the # current index of list i ptr = [ 0 for i in range ( 501 )]
# This function takes an k sorted # lists in the form of 2D array as # an argument. It finds out smallest # range that includes elements from # each of the k lists. def findSmallestRange(arr, N, K):
i, minval, maxval, minrange, minel, maxel, flag, minind = 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
# initializing to 0 index
for i in range (K + 1 ):
ptr[i] = 0
minrange = 10 * * 9
while ( 1 ):
# for maintaining the index of list
# containing the minimum element
minind = - 1
minval = 10 * * 9
maxval = - 10 * * 9
flag = 0
# iterating over all the list
for i in range (K):
# if every element of list[i] is
# traversed then break the loop
if (ptr[i] = = N):
flag = 1
break
# find minimum value among all the list
# elements pointing by the ptr[] array
if (ptr[i] < N and arr[i][ptr[i]] < minval):
minind = i # update the index of the list
minval = arr[i][ptr[i]]
# find maximum value among all the
# list elements pointing by the ptr[] array
if (ptr[i] < N and arr[i][ptr[i]] > maxval):
maxval = arr[i][ptr[i]]
# if any list exhaust we will
# not get any better answer,
# so break the while loop
if (flag):
break
ptr[minind] + = 1
# updating the minrange
if ((maxval - minval) < minrange):
minel = minval
maxel = maxval
minrange = maxel - minel
print ( "The smallest range is [" , minel, maxel, "]" )
# Driver code if __name__ = = '__main__' :
arr = [
[ 4 , 7 , 9 , 12 , 15 ],
[ 0 , 8 , 10 , 14 , 20 ],
[ 6 , 12 , 16 , 30 , 50 ]
]
K = len (arr)
# Function call
findSmallestRange(arr, N, K)
# This code is contributed by mohit kumar |
// C# program to finds out smallest // range that includes elements from // each of the given sorted lists. using System;
class GFG {
static int N = 5;
// array for storing the current index of list i
static int [] ptr = new int [501];
// This function takes an k sorted
// lists in the form of 2D array as
// an argument. It finds out smallest range
// that includes elements from each of the k lists.
static void findSmallestRange( int [, ] arr, int N, int K)
{
int i, minval, maxval, minrange,
minel = 0, maxel = 0, flag, minind;
// initializing to 0 index;
for (i = 0; i <= K; i++) {
ptr[i] = 0;
}
minrange = int .MaxValue;
while ( true ) {
// for maintaining the index of
// list containing the minimum element
minind = -1;
minval = int .MaxValue;
maxval = int .MinValue;
flag = 0;
// iterating over all the list
for (i = 0; i < K; i++) {
// if every element of list[i]
// is traversed then break the loop
if (ptr[i] == N) {
flag = 1;
break ;
}
// find minimum value among all the
// list elements pointing by the ptr[] array
if (ptr[i] < N && arr[i, ptr[i]] < minval) {
minind
= i; // update the index of the list
minval = arr[i, ptr[i]];
}
// find maximum value among all the
// list elements pointing by the ptr[] array
if (ptr[i] < N && arr[i, ptr[i]] > maxval) {
maxval = arr[i, ptr[i]];
}
}
// if any list exhaust we will
// not get any better answer,
// so break the while loop
if (flag == 1) {
break ;
}
ptr[minind]++;
// updating the minrange
if ((maxval - minval) < minrange) {
minel = minval;
maxel = maxval;
minrange = maxel - minel;
}
}
Console.WriteLine( "The smallest range is"
+ "[{0}, {1}]\n" ,
minel, maxel);
}
// Driver's code
public static void Main(String[] args)
{
int [, ] arr = { { 4, 7, 9, 12, 15 },
{ 0, 8, 10, 14, 20 },
{ 6, 12, 16, 30, 50 } };
int K = arr.GetLength(0);
// Function call
findSmallestRange(arr, N, K);
}
} // This code has been contributed by 29AjayKumar |
// Javascript program to finds out smallest range that includes // elements from each of the given sorted lists. let N = 5; // array for storing the current index of list i let ptr= new Array(501);
// This function takes an k sorted lists in the form of // 2D array as an argument. It finds out smallest range
// that includes elements from each of the k lists.
function findSmallestRange(arr,n,k)
{ let i, minval, maxval, minrange, minel = 0, maxel = 0, flag, minind;
// initializing to 0 index;
for (i = 0; i <= k; i++) {
ptr[i] = 0;
}
minrange = Number.MAX_VALUE;
while ( true ) {
// for maintaining the index of list containing the minimum element
minind = -1;
minval = Number.MAX_VALUE;
maxval = Number.MIN_VALUE;
flag = 0;
// iterating over all the list
for (i = 0; i < k; i++) {
// if every element of list[i] is traversed then break the loop
if (ptr[i] == n) {
flag = 1;
break ;
}
// find minimum value among all the list elements pointing by the ptr[] array
if (ptr[i] < n && arr[i][ptr[i]] < minval) {
minind = i; // update the index of the list
minval = arr[i][ptr[i]];
}
// find maximum value among all the list elements pointing by the ptr[] array
if (ptr[i] < n && arr[i][ptr[i]] > maxval) {
maxval = arr[i][ptr[i]];
}
}
// if any list exhaust we will not get any better answer, so break the while loop
if (flag == 1) {
break ;
}
ptr[minind]++;
// updating the minrange
if ((maxval - minval) < minrange) {
minel = minval;
maxel = maxval;
minrange = maxel - minel;
}
}
document.write( "The smallest range is [" +minel+ ", " +maxel+ "]<br>" );
} // Driver program to test above function let arr = [ [4, 7, 9, 12, 15],
[0, 8, 10, 14, 20],
[6, 12, 16, 30, 50]
]
let k = arr.length; findSmallestRange(arr, N, k); // This code is contributed by unknown2108 |
The smallest range is [6, 8]
Time complexity: O(N * K2)
Space complexity: O(K)
The smallest range containing elements from k lists using Min-Heap:
Min-Heap can be used to find the maximum and minimum value in logarithmic time or log k time instead of linear time. Rest of the approach remains the same.
Follow the given steps to solve the problem:
- create a Min-Heap to store K elements, one from each array, and a variable minrange initialized to a maximum value and also keep a variable max to store the maximum integer.
- Initially put the first element from each list and store the maximum value in max.
-
Repeat the following steps until at least one list exhausts :
- To find the minimum value or min, use the top or root of the Min heap which is the minimum element.
- Now update the minrange if the current (max-min) is less than minrange.
- remove the top or root element from the priority queue, insert the next element from the list containing the min element, and update the max with the new element inserted.
Below is the Implementation of the above approach:
// C++ program to finds out smallest range that includes // elements from each of the given sorted lists. #include <bits/stdc++.h> using namespace std;
#define N 5 // A min heap node struct MinHeapNode {
// The element to be stored
int element;
// index of the list from which the element is taken
int i;
// index of the next element to be picked from list
int j;
}; // Prototype of a utility function to swap two min heap // nodes void swap(MinHeapNode* x, MinHeapNode* y);
// A class for Min Heap class MinHeap {
// pointer to array of elements in heap
MinHeapNode* harr;
// size of min heap
int heap_size;
public :
// Constructor: creates a min heap of given size
MinHeap(MinHeapNode a[], int size);
// to heapify a subtree with root at given index
void MinHeapify( int );
// to get index of left child of node at index i
int left( int i) { return (2 * i + 1); }
// to get index of right child of node at index i
int right( int i) { return (2 * i + 2); }
// to get the root
MinHeapNode getMin() { return harr[0]; }
// to replace root with new node x and heapify() new
// root
void replaceMin(MinHeapNode x)
{
harr[0] = x;
MinHeapify(0);
}
}; // Constructor: Builds a heap from a // given array a[] of given size MinHeap::MinHeap(MinHeapNode a[], int size)
{ heap_size = size;
harr = a; // store address of array
int i = (heap_size - 1) / 2;
while (i >= 0) {
MinHeapify(i);
i--;
}
} // A recursive method to heapify a subtree with root at // given index. This method assumes that the subtrees // are already heapified void MinHeap::MinHeapify( int i)
{ int l = left(i);
int r = right(i);
int smallest = i;
if (l < heap_size && harr[l].element < harr[i].element)
smallest = l;
if (r < heap_size
&& harr[r].element < harr[smallest].element)
smallest = r;
if (smallest != i) {
swap(harr[i], harr[smallest]);
MinHeapify(smallest);
}
} // This function takes an K sorted lists in the form of // 2D array as an argument. It finds out smallest range // that includes elements from each of the k lists. void findSmallestRange( int arr[][N], int K)
{ // Create a min heap with k heap nodes. Every heap node
// has first element of an list
int range = INT_MAX;
int min = INT_MAX, max = INT_MIN;
int start, end;
MinHeapNode* harr = new MinHeapNode[K];
for ( int i = 0; i < K; i++) {
// Store the first element
harr[i].element = arr[i][0];
// index of list
harr[i].i = i;
// Index of next element to be stored
// from list
harr[i].j = 1;
// store max element
if (harr[i].element > max)
max = harr[i].element;
}
// Create the heap
MinHeap hp(harr, K);
// Now one by one get the minimum element from min
// heap and replace it with next element of its list
while (1) {
// Get the minimum element and store it in output
MinHeapNode root = hp.getMin();
// update min
min = hp.getMin().element;
// update range
if (range > max - min + 1) {
range = max - min + 1;
start = min;
end = max;
}
// Find the next element that will replace current
// root of heap. The next element belongs to same
// list as the current root.
if (root.j < N) {
root.element = arr[root.i][root.j];
root.j += 1;
// update max element
if (root.element > max)
max = root.element;
}
// break if we have reached end of any list
else
break ;
// Replace root with next element of list
hp.replaceMin(root);
}
cout << "The smallest range is "
<< "[" << start << " " << end << "]" << endl;
;
} // Driver's code int main()
{ int arr[][N] = { { 4, 7, 9, 12, 15 },
{ 0, 8, 10, 14, 20 },
{ 6, 12, 16, 30, 50 } };
int K = sizeof (arr) / sizeof (arr[0]);
// Function call
findSmallestRange(arr, K);
return 0;
} |
// Java program to find out smallest // range that includes elements from // each of the given sorted lists. class GFG {
// A min heap node
static class Node {
// The element to be stored
int ele;
// index of the list from which
// the element is taken
int i;
// index of the next element
// to be picked from list
int j;
Node( int a, int b, int c)
{
this .ele = a;
this .i = b;
this .j = c;
}
}
// A class for Min Heap
static class MinHeap {
Node[] harr; // array of elements in heap
int size; // size of min heap
// Constructor: creates a min heap
// of given size
MinHeap(Node[] arr, int size)
{
this .harr = arr;
this .size = size;
int i = (size - 1 ) / 2 ;
while (i >= 0 ) {
MinHeapify(i);
i--;
}
}
// to get index of left child
// of node at index i
int left( int i) { return 2 * i + 1 ; }
// to get index of right child
// of node at index i
int right( int i) { return 2 * i + 2 ; }
// to heapify a subtree with
// root at given index
void MinHeapify( int i)
{
int l = left(i);
int r = right(i);
int small = i;
if (l < size && harr[l].ele < harr[i].ele)
small = l;
if (r < size && harr[r].ele < harr[small].ele)
small = r;
if (small != i) {
swap(small, i);
MinHeapify(small);
}
}
void swap( int i, int j)
{
Node temp = harr[i];
harr[i] = harr[j];
harr[j] = temp;
}
// to get the root
Node getMin() { return harr[ 0 ]; }
// to replace root with new node x
// and heapify() new root
void replaceMin(Node x)
{
harr[ 0 ] = x;
MinHeapify( 0 );
}
}
// This function takes an k sorted lists
// in the form of 2D array as an argument.
// It finds out smallest range that includes
// elements from each of the k lists.
static void findSmallestRange( int [][] arr, int K)
{
int range = Integer.MAX_VALUE;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int start = - 1 , end = - 1 ;
int N = arr[ 0 ].length;
// Create a min heap with K heap nodes.
// Every heap node has first element of an list
Node[] arr1 = new Node[K];
for ( int i = 0 ; i < K; i++) {
Node node = new Node(arr[i][ 0 ], i, 1 );
arr1[i] = node;
// store max element
max = Math.max(max, node.ele);
}
// Create the heap
MinHeap mh = new MinHeap(arr1, K);
// Now one by one get the minimum element
// from min heap and replace it with
// next element of its list
while ( true ) {
// Get the minimum element and
// store it in output
Node root = mh.getMin();
// update min
min = root.ele;
// update range
if (range > max - min + 1 ) {
range = max - min + 1 ;
start = min;
end = max;
}
// Find the next element that will
// replace current root of heap.
// The next element belongs to same
// list as the current root.
if (root.j < N) {
root.ele = arr[root.i][root.j];
root.j++;
// update max element
if (root.ele > max)
max = root.ele;
}
// break if we have reached
// end of any list
else
break ;
// Replace root with next element of list
mh.replaceMin(root);
}
System.out.print( "The smallest range is [" + start
+ " " + end + "]" );
}
// Driver's Code
public static void main(String[] args)
{
int arr[][] = { { 4 , 7 , 9 , 12 , 15 },
{ 0 , 8 , 10 , 14 , 20 },
{ 6 , 12 , 16 , 30 , 50 } };
int K = arr.length;
// Function call
findSmallestRange(arr, K);
}
} // This code is contributed by nobody_cares |
import sys
# A min heap node class MinHeapNode:
def __init__( self , element, i, j):
self .element = element
self .i = i
self .j = j
# A class for Min Heap class MinHeap:
def __init__( self , a, size):
self .heap_size = size
self .harr = a # store address of array
i = ( self .heap_size - 1 ) / / 2
while i > = 0 :
self .MinHeapify(i)
i - = 1
def MinHeapify( self , i):
l = self .left(i)
r = self .right(i)
smallest = i
if l < self .heap_size and self .harr[l].element < self .harr[i].element:
smallest = l
if r < self .heap_size and self .harr[r].element < self .harr[smallest].element:
smallest = r
if smallest ! = i:
self .swap(i, smallest)
self .MinHeapify(smallest)
def left( self , i):
return 2 * i + 1
def right( self , i):
return 2 * i + 2
def getMin( self ):
return self .harr[ 0 ]
def replaceMin( self , x):
self .harr[ 0 ] = x
self .MinHeapify( 0 )
def swap( self , i, j):
self .harr[i], self .harr[j] = self .harr[j], self .harr[i]
def findSmallestRange(arr, K):
range_val = sys.maxsize
min_val = sys.maxsize
max_val = - sys.maxsize
start, end = 0 , 0
harr = [MinHeapNode( 0 , i, 1 ) for i in range (K)]
for i in range (K):
harr[i].element = arr[i][ 0 ]
if harr[i].element > max_val:
max_val = harr[i].element
hp = MinHeap(harr, K)
while True :
root = hp.getMin()
min_val = root.element
if range_val > max_val - min_val + 1 :
range_val = max_val - min_val + 1
start = min_val
end = max_val
if root.j < N:
root.element = arr[root.i][root.j]
root.j + = 1
if root.element > max_val:
max_val = root.element
else :
break
hp.replaceMin(root)
print ( "The smallest range is [{} {}]" . format (start, end))
# Driver's code if __name__ = = "__main__" :
arr = [[ 4 , 7 , 9 , 12 , 15 ], [ 0 , 8 , 10 , 14 , 20 ], [ 6 , 12 , 16 , 30 , 50 ]]
K = len (arr)
N = len (arr[ 0 ])
findSmallestRange(arr, K)
|
// C# program to find out smallest // range that includes elements from // each of the given sorted lists. using System;
using System.Collections.Generic;
class GFG {
// A min heap node
public class Node {
// The element to be stored
public int ele;
// index of the list from which
// the element is taken
public int i;
// index of the next element
// to be picked from list
public int j;
public Node( int a, int b, int c)
{
this .ele = a;
this .i = b;
this .j = c;
}
}
// A class for Min Heap
public class MinHeap {
// array of elements in heap
public Node[] harr;
// size of min heap
public int size;
// Constructor: creates a min heap
// of given size
public MinHeap(Node[] arr, int size)
{
this .harr = arr;
this .size = size;
int i = (size - 1) / 2;
while (i >= 0) {
MinHeapify(i);
i--;
}
}
// to get index of left child
// of node at index i
int left( int i) { return 2 * i + 1; }
// to get index of right child
// of node at index i
int right( int i) { return 2 * i + 2; }
// to heapify a subtree with
// root at given index
void MinHeapify( int i)
{
int l = left(i);
int r = right(i);
int small = i;
if (l < size && harr[l].ele < harr[i].ele)
small = l;
if (r < size && harr[r].ele < harr[small].ele)
small = r;
if (small != i) {
swap(small, i);
MinHeapify(small);
}
}
void swap( int i, int j)
{
Node temp = harr[i];
harr[i] = harr[j];
harr[j] = temp;
}
// to get the root
public Node getMin() { return harr[0]; }
// to replace root with new node x
// and heapify() new root
public void replaceMin(Node x)
{
harr[0] = x;
MinHeapify(0);
}
}
// This function takes an K sorted lists
// in the form of 2D array as an argument.
// It finds out smallest range that includes
// elements from each of the k lists.
static void findSmallestRange( int [, ] arr, int K)
{
int range = int .MaxValue;
int min = int .MaxValue;
int max = int .MinValue;
int start = -1, end = -1;
int N = arr.GetLength(0);
// Create a min heap with k heap nodes.
// Every heap node has first element of an list
Node[] arr1 = new Node[K];
for ( int i = 0; i < K; i++) {
Node node = new Node(arr[i, 0], i, 1);
arr1[i] = node;
// store max element
max = Math.Max(max, node.ele);
}
// Create the heap
MinHeap mh = new MinHeap(arr1, K);
// Now one by one get the minimum element
// from min heap and replace it with
// next element of its list
while ( true ) {
// Get the minimum element and
// store it in output
Node root = mh.getMin();
// update min
min = root.ele;
// update range
if (range > max - min + 1) {
range = max - min + 1;
start = min;
end = max;
}
// Find the next element that will
// replace current root of heap.
// The next element belongs to same
// list as the current root.
if (root.j < N) {
root.ele = arr[root.i, root.j];
root.j++;
// update max element
if (root.ele > max)
max = root.ele;
}
else
break ; // break if we have reached
// end of any list
// Replace root with next element of list
mh.replaceMin(root);
}
Console.Write( "The smallest range is [" + start
+ " " + end + "]" );
}
// Driver Code
public static void Main(String[] args)
{
int [, ] arr = { { 4, 7, 9, 12, 15 },
{ 0, 8, 10, 14, 20 },
{ 6, 12, 16, 30, 50 } };
int K = arr.GetLength(0);
findSmallestRange(arr, K);
}
} // This code is contributed by Rajput-Ji |
// Javascript program to find out smallest // range that includes elements from // each of the given sorted lists. class Node { constructor(a, b, c)
{
this .ele = a;
this .i = b;
this .j = c;
}
} // A class for Min Heap class MinHeap { // Array of elements in heap
harr;
// Size of min heap
size;
// Constructor: creates a min heap
// of given size
constructor(arr,size)
{
this .harr = arr;
this .size = size;
let i = Math.floor((size - 1) / 2);
while (i >= 0)
{
this .MinHeapify(i);
i--;
}
}
// To get index of left child
// of node at index i
left(i)
{
return 2 * i + 1;
}
// To get index of right child
// of node at index i
right(i)
{
return 2 * i + 2;
}
// To heapify a subtree with
// root at given index
MinHeapify(i)
{
let l = this .left(i);
let r = this .right(i);
let small = i;
if (l < this .size &&
this .harr[l].ele <
this .harr[i].ele)
small = l;
if (r < this .size &&
this .harr[r].ele <
this .harr[small].ele)
small = r;
if (small != i)
{
this .swap(small, i);
this .MinHeapify(small);
}
}
swap(i, j)
{
let temp = this .harr[i];
this .harr[i] = this .harr[j];
this .harr[j] = temp;
}
// To get the root
getMin()
{
return this .harr[0];
}
// To replace root with new node x
// and heapify() new root
replaceMin(x)
{
this .harr[0] = x;
this .MinHeapify(0);
}
} // This function takes an k sorted lists // in the form of 2D array as an argument. // It finds out smallest range that includes // elements from each of the k lists. function findSmallestRange(arr, k)
{ let range = Number.MAX_VALUE;
let min = Number.MAX_VALUE;
let max = Number.MIN_VALUE;
let start = -1, end = -1;
let n = arr[0].length;
// Create a min heap with k heap nodes.
// Every heap node has first element of an list
let arr1 = new Array(k);
for (let i = 0; i < k; i++)
{
let node = new Node(arr[i][0], i, 1);
arr1[i] = node;
// Store max element
max = Math.max(max, node.ele);
}
// Create the heap
let mh = new MinHeap(arr1, k);
// Now one by one get the minimum element
// from min heap and replace it with
// next element of its list
while ( true )
{
// Get the minimum element and
// store it in output
let root = mh.getMin();
// Update min
min = root.ele;
// Update range
if (range > max - min + 1)
{
range = max - min + 1;
start = min;
end = max;
}
// Find the next element that will
// replace current root of heap.
// The next element belongs to same
// list as the current root.
if (root.j < n)
{
root.ele = arr[root.i][root.j];
root.j++;
// Update max element
if (root.ele > max)
max = root.ele;
}
// Break if we have reached
// end of any list
else
break ;
// Replace root with next element of list
mh.replaceMin(root);
}
document.write( "The smallest range is [" +
start + " " + end + "]" );
} // Driver Code let arr = [ [ 4, 7, 9, 12, 15 ], [ 0, 8, 10, 14, 20 ],
[ 6, 12, 16, 30, 50 ] ];
let k = arr.length; findSmallestRange(arr, k); // This code is contributed by rag2127 |
The smallest range is [6 8]
Time complexity: O(N * K * log K)
Auxiliary Space: O(K)
ANOTHER APPROACH USING PRIORITY QUEUE AND BUILT-IN METHODS
Intuition:
- We declare a Priority Queue<Node> ,Node class consists of current row,current column and current data.
- We first push every details of first column in the queue.
- while pushing elements in the queue , we always keep a track of the maximum element achieved so far.
- While poping the smallest element , we update the min value and compare with range ,ie max-min and if the smaller than previous then we update start to min and end to max.
- Atlast we print start and end.
Implementation
// c++ program to find the smallest range that includes // elements from each of the given sorted lists. #include <bits/stdc++.h> using namespace std;
// Node structure class Node {
public :
int data;
int row;
int nextCol;
Node( int data, int row, int nextCol)
{
this ->data = data;
this ->row = row;
this ->nextCol = nextCol;
}
}; // Custom comparator for min heap struct compare {
bool operator()(Node a, Node b)
{
return a.data > b.data;
}
}; // function to get the smallest range void findSmallestRange(vector<vector< int > >& arr, int n,
int k)
{ // initialize a min heap
priority_queue<Node, vector<Node>, compare> pq;
int maxi = 0; // Maximum element found so far
int range = INT_MAX; // Smallest range found so far
// push first element of each list and also found max
// element
for ( int i = 0; i < k; i++) {
pq.push(Node(arr[i][0], i, 0));
maxi = max(maxi, arr[i][0]);
}
int start = -1; // Start of the smallest range
int end = -1; // End of the smallest range
while (!pq.empty()) {
Node n1 = pq.top(); // Get the minimum element from
// the priority queue
pq.pop();
int min = n1.data; // Current minimum element
// is smaller range found
if (range > maxi - min) {
range = maxi - min; // Update the smallest range
start = min; // Update the start of the smallest
// range
end = maxi; // Update the end of the smallest
// range
}
int nextRow = n1.row; // Next row index
int nextColumn = n1.nextCol; // Next column index
if (n1.nextCol + 1 < n) {
pq.push(Node(
arr[nextRow][nextColumn + 1], nextRow,
nextColumn + 1)); // Push the next element
// from the same list into
// the priority queue
maxi = max(
maxi,
arr[nextRow]
[nextColumn
+ 1]); // Update the maximum element
}
else
break ; // Break if reached the end of any list
}
cout << start << " " << end << endl;
} // Driver Code int main()
{ vector<vector< int > > arr = { { 1, 3, 5, 7, 9 },
{ 0, 2, 4, 6, 8 },
{ 2, 3, 5, 7, 11 } };
int k = 3; // Number of sorted lists
findSmallestRange(arr, k, 3); // Find the smallest range
return 0;
} // This code is contributed by Tapesh(tapeshdua420) |
// Java program to finds out smallest range that includes // elements from each of the given sorted lists. import java.io.*;
import java.util.*;
class Node {
int data;
int row;
int nextCol;
Node( int data, int row, int nextCol)
{
this .data = data;
this .row = row;
this .nextCol = nextCol;
}
} class GFG {
static void findSmallestRange( int [][] arr, int n, int k)
{
PriorityQueue<Node> pq = new PriorityQueue<Node>(
(a, b) -> (a.data - b.data));
int max = 0 ;
int range = Integer.MAX_VALUE;
for ( int i = 0 ; i < k; i++) {
pq.add( new Node(arr[i][ 0 ], i, 0 ));
max = Math.max(max, arr[i][ 0 ]);
}
int res[] = new int [ 2 ];
int start = - 1 ;
int end = - 1 ;
while (!pq.isEmpty()) {
Node n1 = pq.poll();
int min = n1.data;
if (range > max - min) {
range = max - min;
start = min;
end = max;
}
int nextRow = n1.row;
int nextColumn = n1.nextCol;
if (n1.nextCol + 1 < n) {
pq.add(
new Node(arr[nextRow][nextColumn + 1 ],
nextRow, nextColumn + 1 ));
max = Math.max(
max, arr[nextRow][nextColumn + 1 ]);
}
else
break ;
}
System.out.println(start + " " + end);
}
public static void main(String[] args)
{
int arr[][]
= { { 1 , 3 , 5 , 7 , 9 },
{ 0 , 2 , 4 , 6 , 8 },
{ 2 , 3 , 5 , 7 , 11 } };
int k
= arr.length;
findSmallestRange(arr, k, 3 );
}
} // This code is contributed by Raunak Singh |
import heapq
class Node:
def __init__( self , data, row, next_col):
self .data = data
self .row = row
self .next_col = next_col
def __lt__( self , other):
return self .data < other.data
def find_smallest_range(arr, n, k):
min_heap = [] # Create a min-heap to store elements from different arrays in sorted order
max_value = 0 # Initialize the maximum value found so far in the min_heap
smallest_range = float ( "inf" ) # Initialize the smallest range found so far as infinity
start = - 1 # Initialize the start of the smallest range
end = - 1 # Initialize the end of the smallest range
# Add the first element from each array to the min_heap
for i in range (k):
heapq.heappush(min_heap, Node(arr[i][ 0 ], i, 0 ))
max_value = max (max_value, arr[i][ 0 ]) # Update the maximum value found so far
# Process the min_heap until it is empty
while min_heap:
node = heapq.heappop(min_heap) # Get the minimum element from the min_heap
min_value = node.data # Get the value of the minimum element
# Check if the range formed by the current element and the maximum element in min_heap is smaller
# than the smallest range found so far.
if smallest_range > max_value - min_value:
smallest_range = max_value - min_value
start = min_value
end = max_value
row = node.row # Get the row of the current element
next_col = node.next_col # Get the next column index of the current element
# If the current row has more elements, add the next element to the min_heap and update max_value
if next_col + 1 < n:
heapq.heappush(min_heap, Node(arr[row][next_col + 1 ], row, next_col + 1 ))
max_value = max (max_value, arr[row][next_col + 1 ])
else :
break # If the current row has no more elements, exit the loop
print (start, end) # Print the smallest range found
if __name__ = = "__main__" :
arr = [[ 1 , 3 , 5 , 7 , 9 ], [ 0 , 2 , 4 , 6 , 8 ], [ 2 , 3 , 5 , 7 , 11 ]]
k = 3
find_smallest_range(arr, k, 3 )
|
// C# program to find the smallest range that includes // elements from each of the given sorted lists. using System;
using System.Collections.Generic;
public class Node : IComparable<Node>
{ public int Data { get ; private set ; }
public int Row { get ; private set ; }
public int NextCol { get ; private set ; }
public Node( int data, int row, int nextCol)
{
Data = data;
Row = row;
NextCol = nextCol;
}
public int CompareTo(Node other)
{
return Data.CompareTo(other.Data);
}
} public class Program
{ public static void FindSmallestRange(List<List< int >> arr, int k, int n)
{
var minHeap = new MinHeap<Node>(); // Create a min-heap to store elements from different arrays in sorted order
int maxValue = 0; // Initialize the maximum value found so far in the min_heap
int smallestRange = int .MaxValue; // Initialize the smallest range found so far as infinity
int start = -1; // Initialize the start of the smallest range
int end = -1; // Initialize the end of the smallest range
// Add the first element from each array to the min_heap
for ( int i = 0; i < k; i++)
{
var node = new Node(arr[i][0], i, 0);
minHeap.Add(node);
maxValue = Math.Max(maxValue, arr[i][0]); // Update the maximum value found so far
}
// Process the min_heap until it is empty
while (minHeap.Count > 0)
{
var node = minHeap.ExtractMin(); // Get the minimum element from the min_heap
int minValue = node.Data; // Get the value of the minimum element
// Check if the range formed by the current element and the maximum element in min_heap is smaller
// than the smallest range found so far.
if (smallestRange > maxValue - minValue)
{
smallestRange = maxValue - minValue;
start = minValue;
end = maxValue;
}
int row = node.Row; // Get the row of the current element
int nextCol = node.NextCol; // Get the next column index of the current element
// If the current row has more elements, add the next element to the min_heap and update maxValue
if (nextCol + 1 < n)
{
var nextNode = new Node(arr[row][nextCol + 1], row, nextCol + 1);
minHeap.Add(nextNode);
maxValue = Math.Max(maxValue, arr[row][nextCol + 1]);
}
else
{
break ; // If the current row has no more elements, exit the loop
}
}
Console.WriteLine($ "{start} {end}" ); // Print the smallest range found
}
//Driver Code public static void Main( string [] args)
{
List<List< int >> arr = new List<List< int >>()
{
new List< int >(){1, 3, 5, 7, 9},
new List< int >(){0, 2, 4, 6, 8},
new List< int >(){2, 3, 5, 7, 11}
};
int k = 3;
int n = 5;
FindSmallestRange(arr, k, n);
}
} public class MinHeap<T> where T : IComparable<T>
{ private List<T> heap;
public MinHeap()
{
heap = new List<T>();
}
public int Count { get { return heap.Count; } }
public void Add(T item)
{
heap.Add(item);
int currentIndex = heap.Count - 1;
while (currentIndex > 0)
{
int parentIndex = (currentIndex - 1) / 2;
if (heap[currentIndex].CompareTo(heap[parentIndex]) >= 0)
break ;
Swap(currentIndex, parentIndex);
currentIndex = parentIndex;
}
}
public T ExtractMin()
{
int lastIndex = heap.Count - 1;
T min = heap[0];
heap[0] = heap[lastIndex];
heap.RemoveAt(lastIndex);
Heapify(0);
return min;
}
private void Heapify( int index)
{
int left = index * 2 + 1;
int right = index * 2 + 2;
int smallest = index;
if (left < heap.Count && heap[left].CompareTo(heap[smallest]) < 0)
smallest = left;
if (right < heap.Count && heap[right].CompareTo(heap[smallest]) < 0)
smallest = right;
if (smallest != index)
{
Swap(index, smallest);
Heapify(smallest);
}
}
private void Swap( int i, int j)
{
T temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
} |
// Node class class Node { constructor(data, row, nextCol) {
this .data = data;
this .row = row;
this .nextCol = nextCol;
}
} // Custom comparator for min heap class MinHeap { constructor() {
this .heap = [];
}
push(node) {
this .heap.push(node);
this .heapifyUp();
}
pop() {
if ( this .heap.length === 0) return null ;
const root = this .heap[0];
const lastNode = this .heap.pop();
if ( this .heap.length > 0) {
this .heap[0] = lastNode;
this .heapifyDown();
}
return root;
}
heapifyUp() {
let currentIndex = this .heap.length - 1;
while (currentIndex > 0) {
const parentIndex = Math.floor((currentIndex - 1) / 2);
if ( this .heap[currentIndex].data < this .heap[parentIndex].data) {
[ this .heap[currentIndex], this .heap[parentIndex]] =
[ this .heap[parentIndex], this .heap[currentIndex]];
currentIndex = parentIndex;
} else {
break ;
}
}
}
heapifyDown() {
let currentIndex = 0;
while ( true ) {
let leftChildIndex = 2 * currentIndex + 1;
let rightChildIndex = 2 * currentIndex + 2;
let swapIndex = currentIndex;
if (leftChildIndex < this .heap.length &&
this .heap[leftChildIndex].data < this .heap[swapIndex].data) {
swapIndex = leftChildIndex;
}
if (rightChildIndex < this .heap.length &&
this .heap[rightChildIndex].data < this .heap[swapIndex].data) {
swapIndex = rightChildIndex;
}
if (swapIndex !== currentIndex) {
[ this .heap[currentIndex], this .heap[swapIndex]] =
[ this .heap[swapIndex], this .heap[currentIndex]];
currentIndex = swapIndex;
} else {
break ;
}
}
}
} // Function to find the smallest range function findSmallestRange(arr, k, n) {
const pq = new MinHeap();
let maxi = 0;
let range = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < k; i++) {
pq.push( new Node(arr[i][0], i, 0));
maxi = Math.max(maxi, arr[i][0]);
}
let start = -1;
let end = -1;
while (pq.heap.length > 0) {
const n1 = pq.pop();
const min = n1.data;
if (range > maxi - min) {
range = maxi - min;
start = min;
end = maxi;
}
const nextRow = n1.row;
const nextColumn = n1.nextCol;
if (n1.nextCol + 1 < n) {
pq.push( new Node(arr[nextRow][nextColumn + 1], nextRow, nextColumn + 1));
maxi = Math.max(maxi, arr[nextRow][nextColumn + 1]);
} else {
break ;
}
}
console.log(start, end);
} // Driver Code const arr = [ [1, 3, 5, 7, 9],
[0, 2, 4, 6, 8],
[2, 3, 5, 7, 11]
]; const k = 3; const n = 5; findSmallestRange(arr, k, n); |
1 2
Time complexity: O(N * K * log K)
Auxiliary Space: O(K) since at worst case only k elements are in the priority Queue.