
С обзиром на 2Д цели низ арр [] [] реда к * н где је сваки ред сортиран у узлазном редоследу. Ваш задатак је пронаћи најмањи опсег који укључује барем један елемент од сваког од њих К Листе. Ако се нађе више од једног таквих распона, вратите се први.
Примери:
Улаз: арр [] [] = [[4 7 9 12 15]
[0 8 10 14 20]
[6 12 16 30 50]]
Излаз: 6 8
Објашњење: Најмањи опсег формиран је по броју 7 са прве листе 8 са друге листе и 6 са треће листе.Улаз: арр [] [] = [[2 4]
[1 7]
[20 40]]
Излаз: 4 20
Објашњење: Распон [4 20] садржи 4 7 20 који садржи елемент из свих три низа.
Табела садржаја
- [Наивни приступ] - Коришћење К Поинтера - О (Н К ^ 2) Време и О (К) Простор
- [Бољи приступ] Коришћење два показивача - О (Н * К Лог (Н * К)) Време и О (Н * К) Простор
- [Ефикасан приступ] - Коришћење мин хеап - о (н к лог к) време и о (к) простора
[Наивни приступ] - Коришћење К Поинтера - О (Н К ^ 2) Време и О (К) Простор
Идеја је да КС покаже један за сваку листу почевши од индекса 0. На сваком кораку узмите мин и мак струјних К елемената за формирање домета. До Смањите распон морамо Повећајте мин вредност Пошто не можемо да смањимо макс. (Сви показивачи почињу на 0). Зато померите показивач листе која има Тренутни минимум и ажурирајте опсег. Поновите док се једна листа није исцрпљена.
Корак по примјени корака:
- Креирајте списак показивача Један за сваку листу уноса све почевши од индекса 0.
- Поновите поступак док неко од показивача не досегне крај своје листе.
- У сваком кораку Изаберите тренутне елементе уперавање од стране свих показивача.
- Нађи минимум и максимум Међу тим елементима.
- Израчунајте опсег користећи мин и макс.
- Ако је овај опсег мањи него претходно најбоље ажурирати одговор.
- Помичите се напред списка која је имала минимални елемент.
- Зауставите се када је било који списак исцрпљен и вратите најбољи пронађени најбољи асортиман.
// 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
[Бољи приступ] Коришћење два показивача - О (Н * К Лог (Н * К)) Време и О (Н * К) Простор
C++Идеја је пронаћи најмањи проблем опсега трансформацијом у проблем са клизним прозором преко спојене и сортиране листе свих елемената са листа уноса. Сваки елемент се чува заједно са оригиналним индексом листе за праћење свог извора. После сортирања комбиноване листе вредностима два показивача (
left
иright
) Користи се за дефинисање прозора који се креће кроз листу. Док прозор проширује трагове фреквенције мапа колико је јединствених листа представљено. Када прозор укључује најмање један број са сваке листе алгоритам покушава да га смањи са леве стране да би пронашао мањи валидан распон. Најмањи такав распон који се налази током овог процеса враћа се као резултат.
#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
[Ефикасан приступ] - Коришћење мин хеап - о (н к лог к) време и о (к) простора
Мин-хрпа Може се користити за проналажење минималне вредности у логаритамичко време или дневник К Време уместо линеарног времена. Да бисте пронашли максималну вредност иницијализирамо максималну вредност свих 0 индекса у почетку. За остатак макс. Вриједности у петљи једноставно упоређујемо тренутну максималну вредност са следећом ставком са листе са које се уклања МИН. Остатак приступа остаје исти.
Корак по примјени корака:
- Мин-хрпа Може се користити за проналажење минималне вредности у логаритамичко време или дневник К Време уместо линеарног времена. Да бисте пронашли максималну вредност иницијализирамо максималну вредност свих 0 индекса у почетку. За остатак макс. Вриједности у петљи једноставно упоређујемо тренутну максималну вредност са следећом ставком са листе са које се уклања МИН. Остатак приступа остаје исти.
Креирајте мин-хрпу за чување К елемената један из сваког низа и променљиве минранге иницијализирано на максималну вредност и такође држите променљиву макс да чувате максимални цели број.
- Мин-хрпа Може се користити за проналажење минималне вредности у логаритамичко време или дневник К Време уместо линеарног времена. Да бисте пронашли максималну вредност иницијализирамо максималну вредност свих 0 индекса у почетку. За остатак макс. Вриједности у петљи једноставно упоређујемо тренутну максималну вредност са следећом ставком са листе са које се уклања МИН. Остатак приступа остаје исти.
У почетку ставите први елемент са сваке листе и чувајте максималну вредност у макс .
- Мин-хрпа Може се користити за проналажење минималне вредности у логаритамичко време или дневник К Време уместо линеарног времена. Да бисте пронашли максималну вредност иницијализирамо максималну вредност свих 0 индекса у почетку. За остатак макс. Вриједности у петљи једноставно упоређујемо тренутну максималну вредност са следећом ставком са листе са које се уклања МИН. Остатак приступа остаје исти.
Поновите следеће кораке до барем једне листе испуштања:
- Пронађите минималну вредност или мин Користите врх или корен мин хрпа који је минимални елемент.
- Сада ажурирајте минранге Ако је струја (МАКС-мин) мања од минранге .
- Уклоните горњи или коријенски елемент из реда приоритета Уметните следећи елемент са листе која садржи мин елемент
- Ажурирајте макс са новим елементом уметнути ако је нови елемент већи од претходног макс.
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]);
Излаз
6 8