
Donada una matriu enter 2D arr [] [] d’ordre k * n On es troba cada fila ordenat en ordre ascendent. La vostra tasca és trobar el rang més petit que inclogui almenys un element de cadascun dels K Llistes. Si es troben més d'un d'aquests intervals, tornen el primer.
Exemples:
Entrada: arr [] [] = [[4 7 9 12 15]
[0 8 10 14 20]
[6 12 16 30 50]]
Sortida: 6 8
Explicació: El rang més petit està format pel número 7 de la primera llista 8 de la segona llista i 6 de la tercera llista.Entrada: arr [] [] = [[2 4]
[1 7]
[20 40]]
Sortida: 4 20
Explicació: El rang [4 20] conté 4 7 20 que conté element de les tres matrius.
Taula de contingut
- [Enfocament ingenu] - Utilitzant k punters - o (n k^2) temps i o (k) espai
- [Millor enfocament] Utilitzant dos punters - o (N*k log (n*k)) temps i o (n*k) espai
- [Aproximació eficient] - Utilitzant el temps MIN - O (N K LOG K) Temps i espai O (K)
[Enfocament ingenu] - Utilitzant k punters - o (n k^2) temps i o (k) espai
La idea és mantenir k punters un per a cada llista a partir de l’índex 0. A cada pas, feu el Min i Max dels elements K actuals per formar un rang. A Minimitzar el rang hem de fer -ho Augmenteu el valor mínim Com que no podem disminuir el màxim (tots els indicadors comencen a 0). Així que moveu el punter de la llista que té Mínim actual i actualitzeu el rang. Repetiu fins que s’esgoti una llista.
Implementació pas a pas:
- Creeu una llista de punters Una per a cada llista d’entrada que s’inicia a l’índex 0.
- Repetiu el procés Fins que un dels indicadors arribi al final de la seva llista.
- A cada pas Trieu els elements actuals apuntat per tots els indicadors.
- Troba el Mínim i màxim entre aquests elements.
- Calculeu l’interval Utilitzant els valors MIN i MAX.
- Si aquest rang és més petit que la millor actualització de la resposta anterior.
- Avança el punter de la llista que tenia l’element mínim.
- Atureu -vos quan s’esgota qualsevol llista i retorneu la millor gamma que es troba.
// 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]);
Producció
6 8
[Millor enfocament] Utilitzant dos punters - o (N*k log (n*k)) temps i o (n*k) espai
C++La idea és trobar el problema més reduït transformant -lo en un problema de finestra lliscant sobre una llista fusionada i ordenada de tots els elements de les llistes d’entrada. Cada element s’emmagatzema juntament amb el seu índex de llista original per fer un seguiment de la seva font. Després d’ordenar la llista combinada per valor dos indicadors (
left
iright
) s'utilitzen per definir una finestra que es mou per la llista. A mesura que la finestra amplia un mapa de freqüències rastreja quantes llistes úniques es representen. Quan la finestra inclou almenys un número de cada llista, l'algoritme intenta reduir -lo des de l'esquerra per trobar un rang vàlid més petit. El rang més petit que es troba durant aquest procés es retorni com a resultat.
#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]);
Producció
6 8
[Aproximació eficient] - Utilitzant el temps MIN - O (N K LOG K) Temps i espai O (K)
Min-Hap Es pot utilitzar per trobar el valor mínim en el temps logarítmic o el temps de registre k en lloc del temps lineal. Per trobar el valor màxim, inicialitzem el valor màxim de tots els 0 índexs inicialment. Per a la resta dels valors màxims del bucle, simplement comparem el valor màxim actual amb l’element següent de la llista des de la qual s’està eliminant l’element MIN. La resta de l’enfocament continua sent el mateix.
Implementació pas a pas:
- Min-Hap Es pot utilitzar per trobar el valor mínim en el temps logarítmic o el temps de registre k en lloc del temps lineal. Per trobar el valor màxim, inicialitzem el valor màxim de tots els 0 índexs inicialment. Per a la resta dels valors màxims del bucle, simplement comparem el valor màxim actual amb l’element següent de la llista des de la qual s’està eliminant l’element MIN. La resta de l’enfocament continua sent el mateix.
Creeu un Min-Hap per emmagatzemar K Elements One de cada matriu i una variable minuratge inicialitzat a un valor màxim i també conserveu una variable màxim Per emmagatzemar el màxim nombre enter.
- Min-Hap Es pot utilitzar per trobar el valor mínim en el temps logarítmic o el temps de registre k en lloc del temps lineal. Per trobar el valor màxim, inicialitzem el valor màxim de tots els 0 índexs inicialment. Per a la resta dels valors màxims del bucle, simplement comparem el valor màxim actual amb l’element següent de la llista des de la qual s’està eliminant l’element MIN. La resta de l’enfocament continua sent el mateix.
Inicialment, poseu el primer element de cada llista i emmagatzemeu el valor màxim a màxim .
- Min-Hap Es pot utilitzar per trobar el valor mínim en el temps logarítmic o el temps de registre k en lloc del temps lineal. Per trobar el valor màxim, inicialitzem el valor màxim de tots els 0 índexs inicialment. Per a la resta dels valors màxims del bucle, simplement comparem el valor màxim actual amb l’element següent de la llista des de la qual s’està eliminant l’element MIN. La resta de l’enfocament continua sent el mateix.
Repetiu els passos següents fins que almenys una llista esgoti:
- Cerqueu el valor mínim o min Utilitzeu la part superior o l’arrel del munt Min que és l’element mínim.
- Ara actualitzeu el minuratge Si el corrent (màxim-min) és inferior a minuratge .
- Elimineu l'element superior o arrel de la cua de prioritat Inseriu l'element següent de la llista que conté l'element MIN
- Actualitzeu el màxim amb el nou element inserit si el nou element és superior al màxim.
C++
Java #include
Python 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)); } }
C# 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])
JavaScript 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
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]);
Producció
6 8