logo

הטווח הקטן ביותר עם אלמנטים מרשימות מיון

נסה את זה בתרגול GFG ' title=

ניתן מערך שלם דו -ממדי arr [] [] של סדר k * n איפה כל שורה נמצאת מְמוּיָן בסדר עולה. המשימה שלך היא למצוא את הטווח הקטן ביותר הכולל לפחות אלמנט אחד מכל אחד מה-  ק  רשימות. אם יותר מטווחים כאלה נמצאים חוזר הראשון.

דוגמאות:  



קֶלֶט: arr [] [] = [[4 7 9 12 15]
[0 8 10 14 20]
[6 12 16 30 50]]
תְפוּקָה: 6 8
הֶסבֵּר: הטווח הקטן ביותר נוצר על ידי מספר 7 מהרשימה הראשונה 8 מהרשימה השנייה ו -6 מהרשימה השלישית.

קֶלֶט: arr [] [] = [[2 4]
[1 7]
[20 40]]
תְפוּקָה: 4 20
הֶסבֵּר: הטווח [4 20] מכיל 4 7 20 המכיל אלמנט מכל שלושת המערכים.

טבלת תוכן



[גישה נאיבית] - שימוש במצבי K - O (n K^2) זמן ו- O (k)

הרעיון הוא לשמור על מצביני K אחד לכל רשימה המתחילה באינדקס 0. בכל שלב קח את דקות ומקסימום מבין מרכיבי K הנוכחיים ליצירת טווח. אֶל למזער את הטווח אנחנו חייבים הגדל את ערך ה- MIN מכיוון שאיננו יכולים להקטין את המקסימום (כל המצביעים מתחילים ב 0). אז הזז את מצביע הרשימה שיש לו את המינימום הנוכחי ולעדכן את הטווח. חזור על כך עד שרשימה אחת מותשת.

יישום שלב אחר שלב:

  • צור רשימת מצביעים אחת לכל רשימת קלט, הכל מתחיל באינדקס 0.
  • חזור על התהליך עד שאחד המצבאים יגיע לסוף הרשימה שלה.
  • בכל שלב בחר את האלמנטים הנוכחיים מצביע על ידי כל ההצעות.
  • מצא את מינימום ומקסימום בין אותם אלמנטים.
  • חשב את הטווח באמצעות ערכי Min ו- Max.
  • אם הטווח הזה קטן יותר מאשר העדכנו את התשובה הקודמת הטובה ביותר.
  • קדימה את המצביע מהרשימה שהייתה באלמנט המינימלי.
  • עצור כאשר כל רשימה מותשת ולהחזיר את הטווח הטוב ביותר שנמצא.
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]); 

תְפוּקָה
6 8

[גישה טובה יותר] באמצעות שני מצביע - o (n*k log (n*k)) זמן ומרחב O (n*k)

הרעיון הוא למצוא את בעיית הטווח הקטנה ביותר על ידי הפיכתה לבעיית חלון הזזה ברשימה ממוזגת וממיונה של כל האלמנטים מרשימות הקלט. כל אלמנט מאוחסן יחד עם מדד הרשימה המקורי שלו כדי לעקוב אחר המקור שלו. לאחר מיון הרשימה המשולבת לפי ערך שתי מצביעים (leftוכןright) משמשים להגדרת חלון העובר ברשימה. כאשר החלון מרחיב מפת תדרים עוקבת אחר כמה רשימות ייחודיות מיוצגות. כאשר החלון כולל מספר אחד לפחות מכל רשימה האלגוריתם מנסה לכווץ אותו משמאל כדי למצוא טווח תקף קטן יותר. הטווח הקטן ביותר כזה שנמצא בתהליך זה מוחזר כתוצאה.



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]); 

תְפוּקָה
6 8

[גישה יעילה] - שימוש ב- Min Heam - O (n k log k) זמן ו- O (k) שטח

דקה-עפר ניתן להשתמש כדי למצוא את הערך המינימלי בזמן לוגריתמי או זמן יומן k במקום זמן ליניארי. כדי למצוא את הערך המקסימלי אנו מאתחל את הערך המקסימלי של כל 0 האינדקסים בתחילה. עבור שאר ערכי המקסימום בלולאה אנו פשוט משווים את הערך המקסימלי הנוכחי לבין הפריט הבא מהרשימה ממנה מוסר פריט Min. שאר הגישה נותרה זהה. 

יישום שלב אחר שלב:

  • דקה-עפר ניתן להשתמש כדי למצוא את הערך המינימלי בזמן לוגריתמי או זמן יומן k במקום זמן ליניארי. כדי למצוא את הערך המקסימלי אנו מאתחל את הערך המקסימלי של כל 0 האינדקסים בתחילה. עבור שאר ערכי המקסימום בלולאה אנו פשוט משווים את הערך המקסימלי הנוכחי לבין הפריט הבא מהרשימה ממנה מוסר פריט Min. שאר הגישה נותרה זהה. 

    צור ערפת דקה לאחסון אלמנטים k אחד מכל מערך ומשתנה מינראנג ' אתחול לערך מקסימאלי וגם לשמור על משתנה מקס לאחסון שלם המרבי.

  • דקה-עפר ניתן להשתמש כדי למצוא את הערך המינימלי בזמן לוגריתמי או זמן יומן k במקום זמן ליניארי. כדי למצוא את הערך המקסימלי אנו מאתחל את הערך המקסימלי של כל 0 האינדקסים בתחילה. עבור שאר ערכי המקסימום בלולאה אנו פשוט משווים את הערך המקסימלי הנוכחי לבין הפריט הבא מהרשימה ממנה מוסר פריט Min. שאר הגישה נותרה זהה. 

    תחילה שים את האלמנט הראשון מכל רשימה ואחסן את הערך המרבי ב מקס ו

  • דקה-עפר ניתן להשתמש כדי למצוא את הערך המינימלי בזמן לוגריתמי או זמן יומן k במקום זמן ליניארי. כדי למצוא את הערך המקסימלי אנו מאתחל את הערך המקסימלי של כל 0 האינדקסים בתחילה. עבור שאר ערכי המקסימום בלולאה אנו פשוט משווים את הערך המקסימלי הנוכחי לבין הפריט הבא מהרשימה ממנה מוסר פריט Min. שאר הגישה נותרה זהה. 

    חזור על השלבים הבאים עד שלפחות רשימה אחת תמצה: 

    • מצא את הערך המינימלי או דקה השתמש בחלק העליון או בשורש של ערימת ה- MIN שהוא האלמנט המינימלי.
    • כעת עדכן את מינראנג ' אם הזרם (Max-min) הוא פחות מ מינראנג ' ו
    • הסר את אלמנט החלק העליון או השורש מתור העדיפות הכנס את האלמנט הבא מהרשימה המכילה את אלמנט ה- MIN
    • עדכן את ה- MAX עם האלמנט החדש שהוכנס אם האלמנט החדש גדול מהמקסימום הקודם.
דקה-עפר ניתן להשתמש כדי למצוא את הערך המינימלי בזמן לוגריתמי או זמן יומן k במקום זמן ליניארי. כדי למצוא את הערך המקסימלי אנו מאתחל את הערך המקסימלי של כל 0 האינדקסים בתחילה. עבור שאר ערכי המקסימום בלולאה אנו פשוט משווים את הערך המקסימלי הנוכחי לבין הפריט הבא מהרשימה ממנה מוסר פריט Min. שאר הגישה נותרה זהה. 

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]); 

תְפוּקָה
6 8