logo

Najmniejszy zakres z elementami z k posortowanych list

Wypróbuj w praktyce GfG ' title=

Biorąc pod uwagę tablicę liczb całkowitych 2d arr[][] porządku k*n gdzie znajduje się każdy wiersz posortowane w kolejności rosnącej. Twoim zadaniem jest znalezienie najmniejszego zakresu zawierającego co najmniej jeden element z każdego z nich  K  listy. Jeśli zostanie znalezionych więcej niż jeden taki zakres, zwróć pierwszy.

Przykłady:  



Wejście: tablica[][] = [[ 4 7 9 12 15 ]
[0 8 10 14 20]
[6 12 16 30 50 ]]
Wyjście: 6 8
Wyjaśnienie: Najmniejszy zakres tworzy liczba 7 z pierwszej listy, 8 z drugiej listy i 6 z trzeciej listy.

Wejście: tablica[][] = [[ 2 4 ]
[1 7]
[20 40]]
Wyjście: 4 20
Wyjaśnienie: Zakres [4 20] zawiera liczbę 4 7 20, która zawiera elementy ze wszystkich trzech tablic.

Spis treści



[Podejście naiwne] - Używanie K wskaźników - O(n k^2) czasu i O(k) przestrzeni

Pomysł jest taki, aby zachować k wskaźników po jednym dla każdej listy, zaczynając od indeksu 0. Na każdym kroku wykonaj: min. i maks bieżących elementów K, tworząc zakres. Do zminimalizować zasięg musimy zwiększyć wartość minimalną ponieważ nie możemy zmniejszyć maksimum (wszystkie wskaźniki zaczynają się od 0). Zatem przesuń wskaźnik na listę zawierającą aktualne minimum i zaktualizuj zakres. Powtarzaj aż do wyczerpania jednej listy.

Wdrażanie krok po kroku:

  • Utwórz listę wskaźników po jednym dla każdej listy wejściowej, wszystkie zaczynające się od indeksu 0.
  • Powtórz proces dopóki jeden ze wskaźników nie osiągnie końca swojej listy.
  • Na każdym kroku wybierz bieżące elementy wskazywany przez wszystkie wskazówki.
  • Znajdź minimalne i maksymalne wśród tych elementów.
  • Oblicz zakres używając wartości min i max.
  • Jeśli ten zakres jest mniejszy niż poprzednia najlepsza aktualizacja odpowiedzi.
  • Przesuń wskaźnik do przodu listy, która zawierała element minimalny.
  • Zatrzymaj się, gdy jakakolwiek lista się wyczerpie i zwróć najlepszy znaleziony zakres.
C++
// C++ program to find the smallest range // that includes at least one element from // each of the k sorted lists using k pointers #include    #include  #include  using namespace std; vector<int> findSmallestRange(vector<vector<int>>& arr) {    int k = arr.size();   int n = arr[0].size();   // Pointers for each of the k rows  vector<int> ptr(k 0);  int minRange = INT_MAX;  int start = -1 end = -1;  while (true) {  int minVal = INT_MAX;  int maxVal = INT_MIN;  int minRow = -1;  // Traverse all k rows to get current min and max  for (int i = 0; i < k; i++) {  // If any list is exhausted stop the loop  if (ptr[i] == n) {  return {start end};  }  // Track min value and its row index  if (arr[i][ptr[i]] < minVal) {  minVal = arr[i][ptr[i]];  minRow = i;  }  // Track current max value  if (arr[i][ptr[i]] > maxVal) {  maxVal = arr[i][ptr[i]];  }  }  // Update the result range if a   // smaller range is found  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  start = minVal;  end = maxVal;  }  // Move the pointer of the   // row with minimum value  ptr[minRow]++;  }  return {start end}; } int main() {  vector<vector<int>> arr = {  {4 7 9 12 15}  {0 8 10 14 20}  {6 12 16 30 50}  };  vector<int> res = findSmallestRange(arr);  cout << res[0] << ' ' << res[1];  return 0; } 
Java
// Java program to find the smallest range import java.util.*; class GfG{  static ArrayList<Integer> findSmallestRange(int[][] arr) {  int k = arr.length;  int n = arr[0].length;  // Pointers for each of the k rows  int[] ptr = new int[k];  int minRange = Integer.MAX_VALUE;  int start = -1 end = -1;  while (true) {  int minVal = Integer.MAX_VALUE;  int maxVal = Integer.MIN_VALUE;  int minRow = -1;  // Traverse all k rows to get current min and max  for (int i = 0; i < k; i++) {  // If any list is exhausted stop the loop  if (ptr[i] == n) {  ArrayList<Integer> result = new ArrayList<>();  result.add(start);  result.add(end);  return result;  }  // Track min value and its row index  if (arr[i][ptr[i]] < minVal) {  minVal = arr[i][ptr[i]];  minRow = i;  }  // Track current max value  if (arr[i][ptr[i]] > maxVal) {  maxVal = arr[i][ptr[i]];  }  }  // Update the result range if a smaller range is found  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  start = minVal;  end = maxVal;  }  // Move the pointer of the row with minimum value  ptr[minRow]++;  }  }  public static void main(String[] args) {  int[][] arr = {  {4 7 9 12 15}  {0 8 10 14 20}  {6 12 16 30 50}  };  ArrayList<Integer> res = findSmallestRange(arr);  System.out.println(res.get(0) + ' ' + res.get(1));  } } 
Python
# Python program to find the smallest range def findSmallestRange(arr): k = len(arr) n = len(arr[0]) # Pointers for each of the k rows ptr = [0] * k min_range = float('inf') start = -1 end = -1 while True: min_val = float('inf') max_val = float('-inf') min_row = -1 # Traverse all k rows to get current min and max for i in range(k): # If any list is exhausted stop the loop if ptr[i] == n: return [start end] # Track min value and its row index if arr[i][ptr[i]] < min_val: min_val = arr[i][ptr[i]] min_row = i # Track current max value if arr[i][ptr[i]] > max_val: max_val = arr[i][ptr[i]] # Update the result range if a smaller range is found if max_val - min_val < min_range: min_range = max_val - min_val start = min_val end = max_val # Move the pointer of the row with minimum value ptr[min_row] += 1 if __name__ == '__main__': arr = [ [4 7 9 12 15] [0 8 10 14 20] [6 12 16 30 50] ] res = findSmallestRange(arr) print(res[0] res[1]) 
C#
using System; using System.Collections.Generic; class GfG{  static List<int> findSmallestRange(int[] arr) {  int k = arr.GetLength(0);  int n = arr.GetLength(1);  // Pointers for each of the k rows  int[] ptr = new int[k];   int minRange = int.MaxValue;  int start = -1 end = -1;  while (true) {  int minVal = int.MaxValue;  int maxVal = int.MinValue;  int minRow = -1;  // Traverse all k rows to get current min and max  for (int i = 0; i < k; i++) {  // If any list is exhausted stop the loop  if (ptr[i] == n) {  return new List<int> { start end };  }  int current = arr[i ptr[i]];  if (current < minVal) {  minVal = current;  minRow = i;  }  if (current > maxVal) {  maxVal = current;  }  }  // Update the result range if a smaller range is found  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  start = minVal;  end = maxVal;  }  // Move the pointer of the row with minimum value  ptr[minRow]++;  }  }  public static void Main(string[] args) {  int[] arr = {  { 4 7 9 12 15 }  { 0 8 10 14 20 }  { 6 12 16 30 50 }  };  List<int> res = findSmallestRange(arr);  Console.WriteLine(res[0] + ' ' + res[1]);  } } 
JavaScript
// JavaScript program to find the smallest range function findSmallestRange(arr) {  let k = arr.length;  let n = arr[0].length;  // Pointers for each of the k rows  let ptr = new Array(k).fill(0);  let minRange = Infinity;  let start = -1 end = -1;  while (true) {  let minVal = Infinity;  let maxVal = -Infinity;  let minRow = -1;  // Traverse all k rows to get current min and max  for (let i = 0; i < k; i++) {  // If any list is exhausted stop the loop  if (ptr[i] === n) {  return [start end];  }  // Track min value and its row index  if (arr[i][ptr[i]] < minVal) {  minVal = arr[i][ptr[i]];  minRow = i;  }  // Track current max value  if (arr[i][ptr[i]] > maxVal) {  maxVal = arr[i][ptr[i]];  }  }  // Update the result range if a smaller range is found  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  start = minVal;  end = maxVal;  }  // Move the pointer of the row with minimum value  ptr[minRow]++;  } } const arr = [  [4 7 9 12 15]  [0 8 10 14 20]  [6 12 16 30 50] ]; const res = findSmallestRange(arr); console.log(res[0] + ' ' + res[1]); 

Wyjście
6 8

[Lepsze podejście] Używanie dwóch wskaźników - O(n*k log (n*k)) czasu i O(n*k) przestrzeni

Pomysł polega na znalezieniu najmniejszego problemu zasięgu poprzez przekształcenie go w problem przesuwanego okna na połączonej i posortowanej liście wszystkich elementów z list wejściowych. Każdy element jest przechowywany wraz z oryginalnym indeksem listy w celu śledzenia jego źródła. Po posortowaniu połączonej listy według wartości dwóch wskaźników (leftIright) służą do zdefiniowania okna poruszającego się po liście. W miarę rozszerzania się okna mapa częstotliwości śledzi liczbę reprezentowanych unikalnych list. Gdy okno zawiera co najmniej jedną liczbę z każdej listy, algorytm próbuje ją zmniejszyć od lewej strony, aby znaleźć mniejszy prawidłowy zakres. Jako wynik zwracany jest najmniejszy taki zakres znaleziony podczas tego procesu.



C++
#include    using namespace std; vector<int> findSmallestRange(vector<vector<int>>& arr) {    int k = arr.size();   // Stores the current index for each list  vector<int> pointers(k 0);  // Stores the current smallest range  vector<int> smallestRange = {0 INT_MAX};  while (true) {  int currentMin = INT_MAX currentMax = INT_MIN;  int minListIndex = -1;  // Find the minimum and maximum among current elements of all lists  for (int i = 0; i < k; i++) {  int value = arr[i][pointers[i]];  if (value < currentMin) {  currentMin = value;  minListIndex = i;  }  if (value > currentMax) {  currentMax = value;  }  }  // Update the smallest range if this one is smaller  if (currentMax - currentMin < smallestRange[1] - smallestRange[0]) {  smallestRange[0] = currentMin;  smallestRange[1] = currentMax;  }  // Move the pointer in the list that had the minimum value  pointers[minListIndex]++;  // If that list is exhausted break the loop  if (pointers[minListIndex] == arr[minListIndex].size()) break;  }  return smallestRange; } // Driver code int main() {  vector<vector<int>> arr = {  {4 7 9 12 15}  {0 8 10 14 20}  {6 12 16 30 50}  };  vector<int> result = findSmallestRange(arr);  cout << result[0] << ' ' << result[1];  return 0; } 
Java
import java.util.*; class GfG {  // Function to find the smallest range  public static ArrayList<Integer> findSmallestRange(int[][] arr) {  int k = arr.length; // Number of lists  // Stores the current index for each list  int[] pointers = new int[k];  // Stores the current smallest range  ArrayList<Integer> smallestRange = new ArrayList<>  (Arrays.asList(0 Integer.MAX_VALUE));  // Continue the loop until one list is exhausted  while (true) {  int currentMin = Integer.MAX_VALUE currentMax = Integer.MIN_VALUE;  int minListIndex = -1;  // Find the minimum and maximum among current elements of all lists  for (int i = 0; i < k; i++) {  int value = arr[i][pointers[i]];  // Update the current minimum  if (value < currentMin) {  currentMin = value;  minListIndex = i;  }  // Update the current maximum  if (value > currentMax) {  currentMax = value;  }  }  // Update the smallest range if this one is smaller  if (currentMax - currentMin < smallestRange.get(1) - smallestRange.get(0)) {  smallestRange.set(0 currentMin);  smallestRange.set(1 currentMax);  }  // Move the pointer in the list that had the minimum value  pointers[minListIndex]++;  // If that list is exhausted break the loop  if (pointers[minListIndex] == arr[minListIndex].length) break;  }  return smallestRange; // Return the result as ArrayList  }  // 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}  };  ArrayList<Integer> result = findSmallestRange(arr);  System.out.println(result.get(0) + ' ' + result.get(1));  } } 
Python
def findSmallestRange(arr): k = len(arr) # Number of lists # Stores the current index for each list pointers = [0] * k # Stores the current smallest range smallestRange = [0 float('inf')] # Continue the loop until one list is exhausted while True: currentMin = float('inf') currentMax = -float('inf') minListIndex = -1 # Find the minimum and maximum among current elements of all lists for i in range(k): value = arr[i][pointers[i]] # Update the current minimum if value < currentMin: currentMin = value minListIndex = i # Update the current maximum if value > currentMax: currentMax = value # Update the smallest range if this one is smaller if currentMax - currentMin < smallestRange[1] - smallestRange[0]: smallestRange[0] = currentMin smallestRange[1] = currentMax # Move the pointer in the list that had the minimum value pointers[minListIndex] += 1 # If that list is exhausted break the loop if pointers[minListIndex] == len(arr[minListIndex]): break return smallestRange # Return the result as a list # Driver code if __name__ == '__main__': arr = [ [4 7 9 12 15] [0 8 10 14 20] [6 12 16 30 50] ] result = findSmallestRange(arr) print(result[0] result[1]) 
C#
using System; using System.Collections.Generic; class GfG{  // Function to find the smallest range  public static List<int> findSmallestRange(int[] arr) {  int k = arr.GetLength(0); // Number of lists (rows)  // Stores the current index for each list (row)  int[] pointers = new int[k];  // Stores the current smallest range  List<int> smallestRange = new List<int> { 0 int.MaxValue };  // Continue the loop until one list is exhausted  while (true) {  int currentMin = int.MaxValue currentMax = int.MinValue;  int minListIndex = -1;  // Find the minimum and maximum among current elements   // of all lists  for (int i = 0; i < k; i++) {  int value = arr[i pointers[i]];  // Update the current minimum  if (value < currentMin) {  currentMin = value;  minListIndex = i;  }  // Update the current maximum  if (value > currentMax) {  currentMax = value;  }  }  // Update the smallest range if this one is smaller  if (currentMax - currentMin < smallestRange[1] - smallestRange[0]) {  smallestRange[0] = currentMin;  smallestRange[1] = currentMax;  }  // Move the pointer in the list that had the minimum value  pointers[minListIndex]++;  // If that list is exhausted break the loop  if (pointers[minListIndex] == arr.GetLength(1)) break;  }  return smallestRange; // Return the result as List    }  // 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}  };  List<int> result = findSmallestRange(arr);  Console.WriteLine(result[0] + ' ' + result[1]);  } } 
JavaScript
function findSmallestRange(arr) {  const k = arr.length; // Number of lists  // Stores the current index for each list  let pointers = new Array(k).fill(0);  // Stores the current smallest range  let smallestRange = [0 Number.MAX_VALUE];  // Continue the loop until one list is exhausted  while (true) {  let currentMin = Number.MAX_VALUE currentMax = -Number.MAX_VALUE;  let minListIndex = -1;  // Find the minimum and maximum among current elements of all lists  for (let i = 0; i < k; i++) {  const value = arr[i][pointers[i]];  // Update the current minimum  if (value < currentMin) {  currentMin = value;  minListIndex = i;  }  // Update the current maximum  if (value > currentMax) {  currentMax = value;  }  }  // Update the smallest range if this one is smaller  if (currentMax - currentMin < smallestRange[1] - smallestRange[0]) {  smallestRange[0] = currentMin;  smallestRange[1] = currentMax;  }  // Move the pointer in the list that had the minimum value  pointers[minListIndex]++;  // If that list is exhausted break the loop  if (pointers[minListIndex] === arr[minListIndex].length) break;  }  return smallestRange; // Return the result as an array } // Driver code const arr = [  [4 7 9 12 15]  [0 8 10 14 20]  [6 12 16 30 50] ]; const result = findSmallestRange(arr); console.log(result[0] result[1]); 

Wyjście
6 8

[Efektywne podejście] - Korzystanie z minimalnej sterty - O(n k log k) czasu i O(k) przestrzeni

Min-Sterta można użyć do znalezienia minimalnej wartości w czasie logarytmicznym lub log k zamiast czasu liniowego. Aby znaleźć maksymalną wartość, początkowo inicjujemy maksymalną wartość wszystkich indeksów 0. Dla pozostałych wartości maksymalnych w pętli po prostu porównujemy bieżącą wartość maksymalną z następną pozycją na liście, z której usuwany jest element min. Reszta podejścia pozostaje taka sama. 

Wdrażanie krok po kroku:

  • Min-Sterta można użyć do znalezienia minimalnej wartości w czasie logarytmicznym lub log k zamiast czasu liniowego. Aby znaleźć maksymalną wartość, początkowo inicjujemy maksymalną wartość wszystkich indeksów 0. Dla pozostałych wartości maksymalnych w pętli po prostu porównujemy bieżącą wartość maksymalną z następną pozycją na liście, z której usuwany jest element min. Reszta podejścia pozostaje taka sama. 

    Utwórz Min-Heap do przechowywania K elementów po jednym z każdej tablicy i zmiennej minrange zainicjowany do maksymalnej wartości, a także przechowuje zmienną maks do przechowywania maksymalnej liczby całkowitej.

  • Min-Sterta można użyć do znalezienia minimalnej wartości w czasie logarytmicznym lub log k zamiast czasu liniowego. Aby znaleźć maksymalną wartość, początkowo inicjujemy maksymalną wartość wszystkich indeksów 0. Dla pozostałych wartości maksymalnych w pętli po prostu porównujemy bieżącą wartość maksymalną z następną pozycją na liście, z której usuwany jest element min. Reszta podejścia pozostaje taka sama. 

    Początkowo umieść pierwszy element z każdej listy i zapisz w nim maksymalną wartość maks .

  • Min-Sterta można użyć do znalezienia minimalnej wartości w czasie logarytmicznym lub log k zamiast czasu liniowego. Aby znaleźć maksymalną wartość, początkowo inicjujemy maksymalną wartość wszystkich indeksów 0. Dla pozostałych wartości maksymalnych w pętli po prostu porównujemy bieżącą wartość maksymalną z następną pozycją na liście, z której usuwany jest element min. Reszta podejścia pozostaje taka sama. 

    Powtarzaj poniższe kroki aż do wyczerpania się co najmniej jednej listy: 

    • znajdź wartość minimalną lub min użyj góry lub korzenia sterty Min, która jest elementem minimalnym.
    • Teraz zaktualizuj minrange jeśli prąd (max-min) jest mniejszy niż minrange .
    • Usuń element górny lub główny z kolejki priorytetowej, wstaw kolejny element z listy zawierającej element min
    • Zaktualizuj maks., dodając nowy element, jeśli nowy element jest większy niż poprzedni maks.
Min-Sterta można użyć do znalezienia minimalnej wartości w czasie logarytmicznym lub log k zamiast czasu liniowego. Aby znaleźć maksymalną wartość, początkowo inicjujemy maksymalną wartość wszystkich indeksów 0. Dla pozostałych wartości maksymalnych w pętli po prostu porównujemy bieżącą wartość maksymalną z następną pozycją na liście, z której usuwany jest element min. Reszta podejścia pozostaje taka sama. 

C++

#include    using namespace std; // Struct to represent elements in the heap struct Node {  int val row col;  bool operator>(const Node& other) const {  return val > other.val;  } }; // Function to find the smallest range vector<int> findSmallestRange(vector<vector<int>>& arr) {  int N = arr.size(); // Number of rows  int K = arr[0].size(); // Number of columns (same for each row)  priority_queue<Node vector<Node> greater<Node>> pq;  int maxVal = INT_MIN;  // Push the first element of each list into the min-heap  for (int i = 0; i < N; i++) {  pq.push({arr[i][0] i 0});  maxVal = max(maxVal arr[i][0]);  }  int minRange = INT_MAX minEl maxEl;  while (true) {  Node curr = pq.top(); pq.pop();  int minVal = curr.val;  // Update range if better  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  minEl = minVal;  maxEl = maxVal;  }  // If we've reached the end of a list break  if (curr.col + 1 == K) break;  // Push next element from the same list  int nextVal = arr[curr.row][curr.col + 1];  pq.push({nextVal curr.row curr.col + 1});  maxVal = max(maxVal nextVal);  }  return {minEl maxEl}; } // Driver code int main() {  vector<vector<int>> arr = {  {4 7 9 12 15}  {0 8 10 14 20}  {6 12 16 30 50}  };  vector<int> result = findSmallestRange(arr);  cout << result[0] << ' ' << result[1];  return 0; } 
Java
import java.util.*; // Class to represent elements in the heap class Node implements Comparable<Node> {  int val row col;  Node(int val int row int col) {  this.val = val;  this.row = row;  this.col = col;  }  // For min-heap based on value  public int compareTo(Node other) {  return this.val - other.val;  } } class GfG {  // Function to find the smallest range  static ArrayList<Integer> findSmallestRange(int[][] arr) {  int k = arr.length;  int n = arr[0].length;  PriorityQueue<Node> pq = new PriorityQueue<>();  int maxVal = Integer.MIN_VALUE;  // Push the first element of each list into the min-heap  for (int i = 0; i < k; i++) {  pq.add(new Node(arr[i][0] i 0));  maxVal = Math.max(maxVal arr[i][0]);  }  int minRange = Integer.MAX_VALUE minEl = -1 maxEl = -1;  while (true) {  Node curr = pq.poll();  int minVal = curr.val;  // Update range if better  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  minEl = minVal;  maxEl = maxVal;  }  // If we've reached the end of a list break  if (curr.col + 1 == n)  break;  // Push next element from the same list  int nextVal = arr[curr.row][curr.col + 1];  pq.add(new Node(nextVal curr.row curr.col + 1));  maxVal = Math.max(maxVal nextVal);  }  // Return result as ArrayList  ArrayList<Integer> result = new ArrayList<>();  result.add(minEl);  result.add(maxEl);  return result;  }  // 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}  };  ArrayList<Integer> res = findSmallestRange(arr);  System.out.println(res.get(0) + ' ' + res.get(1));  } } 
Python
import heapq # Function to find the smallest range def findSmallestRange(arr): k = len(arr) n = len(arr[0]) heap = [] maxVal = float('-inf') # Push the first element of each  # list into the min-heap for i in range(k): heapq.heappush(heap (arr[i][0] i 0)) maxVal = max(maxVal arr[i][0]) minRange = float('inf') minEl = maxEl = -1 while True: minVal row col = heapq.heappop(heap) # Update range if better if maxVal - minVal < minRange: minRange = maxVal - minVal minEl = minVal maxEl = maxVal # If we've reached the end of a list break if col + 1 == n: break # Push next element from the same list nextVal = arr[row][col + 1] heapq.heappush(heap (nextVal row col + 1)) maxVal = max(maxVal nextVal) return [minEl maxEl] # Driver code if __name__ == '__main__': arr = [ [4 7 9 12 15] [0 8 10 14 20] [6 12 16 30 50] ] res = findSmallestRange(arr) print(res[0] res[1]) 
C#
using System; using System.Collections.Generic; // Class to represent elements in the heap class Node : IComparable<Node> {  public int val row col;  public Node(int val int row int col) {  this.val = val;  this.row = row;  this.col = col;  }  // For min-heap based on value  public int CompareTo(Node other) {  if (this.val != other.val)  return this.val.CompareTo(other.val);  // To avoid duplicate keys in SortedSet  if (this.row != other.row)  return this.row.CompareTo(other.row);  return this.col.CompareTo(other.col);  } } class GfG {  // Function to find the smallest range  static List<int> findSmallestRange(int[] arr) {  int k = arr.GetLength(0);  int n = arr.GetLength(1);  var pq = new SortedSet<Node>();  int maxVal = int.MinValue;  // Push the first element of each list into the min-heap  for (int i = 0; i < k; i++) {  var node = new Node(arr[i 0] i 0);  pq.Add(node);  maxVal = Math.Max(maxVal arr[i 0]);  }  int minRange = int.MaxValue minEl = -1 maxEl = -1;  while (true) {  var curr = GetMin(pq);  pq.Remove(curr);  int minVal = curr.val;  // Update range if better  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  minEl = minVal;  maxEl = maxVal;  }  // If we've reached the end of a list break  if (curr.col + 1 == n)  break;  // Push next element from the same list  int nextVal = arr[curr.row curr.col + 1];  var nextNode = new Node(nextVal curr.row curr.col + 1);  pq.Add(nextNode);  maxVal = Math.Max(maxVal nextVal);  }  return new List<int> { minEl maxEl }; // Return result as List    }  // Helper to get the minimum element (first element in SortedSet)  static Node GetMin(SortedSet<Node> pq) {  foreach (var node in pq)  return node;  return null;  }  // Driver code  static void Main() {  int[] arr = {  {4 7 9 12 15}  {0 8 10 14 20}  {6 12 16 30 50}  };  List<int> res = findSmallestRange(arr);  Console.WriteLine(res[0] + ' ' + res[1]);  } } 
JavaScript
class Node {  constructor(val row col) {  this.val = val;  this.row = row;  this.col = col;  } } // Function to find the smallest range function findSmallestRange(arr) {  const k = arr.length;  const n = arr[0].length;  const heap = new MinHeap();  let maxVal = -Infinity;  // Push the first element of each list into the min-heap  for (let i = 0; i < k; i++) {  heap.push(new Node(arr[i][0] i 0));  maxVal = Math.max(maxVal arr[i][0]);  }  let minRange = Infinity;  let minEl = -1 maxEl = -1;  while (true) {  const curr = heap.pop();  const minVal = curr.val;  // Update range if better  if (maxVal - minVal < minRange) {  minRange = maxVal - minVal;  minEl = minVal;  maxEl = maxVal;  }  // If we've reached the end of a list break  if (curr.col + 1 === n) break;  // Push next element from the same list  const nextVal = arr[curr.row][curr.col + 1];  heap.push(new Node(nextVal curr.row curr.col + 1));  maxVal = Math.max(maxVal nextVal);  }  return [minEl maxEl]; } // Min-heap comparator class MinHeap {  constructor() {  this.heap = [];  }  push(node) {  this.heap.push(node);  this._heapifyUp();  }  pop() {  if (this.size() === 1) return this.heap.pop();  const top = this.heap[0];  this.heap[0] = this.heap.pop();  this._heapifyDown();  return top;  }  top() {  return this.heap[0];  }  size() {  return this.heap.length;  }  _heapifyUp() {  let idx = this.size() - 1;  while (idx > 0) {  let parent = Math.floor((idx - 1) / 2);  if (this.heap[parent].val <= this.heap[idx].val) break;  [this.heap[parent] this.heap[idx]] = [this.heap[idx] this.heap[parent]];  idx = parent;  }  }  _heapifyDown() {  let idx = 0;  const n = this.size();  while (true) {  let left = 2 * idx + 1;  let right = 2 * idx + 2;  let smallest = idx;  if (left < n && this.heap[left].val < this.heap[smallest].val) {  smallest = left;  }  if (right < n && this.heap[right].val < this.heap[smallest].val) {  smallest = right;  }  if (smallest === idx) break;  [this.heap[smallest] this.heap[idx]] = [this.heap[idx] this.heap[smallest]];  idx = smallest;  }  } } // Driver code const arr = [  [4 7 9 12 15]  [0 8 10 14 20]  [6 12 16 30 50] ]; const res = findSmallestRange(arr); console.log(res[0] + ' ' + res[1]); 

Wyjście
6 8