给定 k 个大小为 n 的整数的排序列表,从 k 个列表中的每个列表中找到至少包含元素的最小范围。如果找到多个最小范围,则打印其中任何一个。
例子:
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.
朴素方法:给定 K 个排序列表,找到一个范围,其中每个列表中至少有一个元素。解决这个问题的思路很简单,保持k个指针构成范围内的元素,取k个元素的最小值和最大值就可以形成范围。最初,所有指针都将指向所有 k 个数组的开头。存储范围最大值到最小值。如果必须最小化范围,则必须增加最小值或必须减小最大值。数组排序后,最大值不能减少,但可以增加最小值。要继续增加最小值,请增加包含最小值的列表的指针并更新范围,直到列表之一耗尽。
- 算法:
- 创建一个长度为 k 的额外空间ptr来存储指针和一个初始化为最大值的变量minrange 。
- 最初每个列表的索引都是 0,因此将ptr[0..k] 的每个元素初始化为 0,数组 ptr 将存储范围内元素的索引。
- 重复以下步骤,直到至少一个列表用完:
- 现在找到 ptr[0…k] 数组指向的所有列表的当前元素中的最小值和最大值。
- 如果当前 (max-min) 小于 minrange,则更新 minrange。
- 增加指向当前最小元素的指针。
- 执行:
C++
// C++ program to finds out smallest range that includes
// elements from each of the given sorted lists.
#include
using namespace std;
#define N 5
// 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(int arr[][N], 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 program to test above function
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]);
findSmallestRange(arr, N, k);
return 0;
}
// This code is contributed by Aditya Krishna Namdeo
Java
// 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
Python
# 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
arr = [
[4, 7, 9, 12, 15],
[0, 8, 10, 14, 20],
[6, 12, 16, 30, 50]
]
k = len(arr)
findSmallestRange(arr, N, k)
# This code is contributed by mohit kumar
C#
// 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 maintining 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 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, N, k);
}
}
// This code has been contributed by 29AjayKumar
Javascript
C++
// C++ program to finds out smallest range that includes
// elements from each of the given sorted lists.
#include
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 program to test above functions
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]);
findSmallestRange(arr, k);
return 0;
}
Java
// 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 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;
findSmallestRange(arr, k);
}
}
// This code is contributed by nobody_cares
C#
// 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
输出:
The smallest range is [6 8]
- 复杂度分析:
- 时间复杂度: O(n * k 2 ),在长度为k的数组中找到最大值和最小值所需的时间为O(k),遍历所有长度为n的数组(在最坏的情况下),时间复杂度为 O(n*k),那么总时间复杂度为 O(n*k 2 )。
- 空间复杂度: O(k),需要一个长度为 k 的额外数组,所以空间复杂度为 O(k)
高效的方法:方法保持不变,但可以通过使用 min-heap 或priority queue来降低时间复杂度。最小堆可用于在对数时间或 log k 时间而不是线性时间中找到最大值和最小值。其余方法保持不变。
- 算法:
- 创建一个 Min 堆来存储 k 个元素,每个数组一个元素,一个变量minrange初始化为最大值,并保留一个变量max来存储最大整数。
- 最初放置每个列表中每个元素的第一个元素,并将最大值存储在max 中。
- 重复以下步骤,直到至少一个列表耗尽:
- 要找到最小值或min ,请使用作为最小元素的 Min 堆的顶部或根。
- 如果当前 (max-min) 小于 minrange,现在更新 minrange。
- 从优先级队列中删除顶部或根元素,并从包含最小元素的列表中插入下一个元素,并使用插入的新元素更新最大值。
- 执行:
C++
// C++ program to finds out smallest range that includes
// elements from each of the given sorted lists.
#include
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 program to test above functions
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]);
findSmallestRange(arr, k);
return 0;
}
Java
// 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 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;
findSmallestRange(arr, k);
}
}
// This code is contributed by nobody_cares
C#
// 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
输出:
The smallest range is [6 8]
- 复杂度分析:
- 时间复杂度: O(n * k *log k)。
要在长度为 k 的最小堆中找到最大值和最小值所需的时间为 O(log k),并且要遍历所有长度为 n 的 k 数组(在最坏的情况下),时间复杂度为 O(n*k),那么总时间复杂度是 O(n * k *log k)。 - 空间复杂度: O(k)。
优先级队列将存储 k 个元素,因此空间复杂度为 O(k)
- 时间复杂度: O(n * k *log k)。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。