Skip to content

Commit 05fd08e

Browse files
authored
Create README.md
1 parent 17b2eed commit 05fd08e

File tree

1 file changed

+273
-0
lines changed
  • 19 - Heap Data Structure Problems/15 - Smallest Range Covering Element from K Lists

1 file changed

+273
-0
lines changed
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
<h1 align='center'>Smallest - Range - Covering - Element From - K Lists</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Smallest Range Covering Element From k Lists](https://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/)
6+
7+
![image](https://github.com/user-attachments/assets/5a5951b7-1f5e-40e4-bde6-99270a0de706)
8+
9+
## Problem Explanation
10+
You are given `k` sorted lists of integers. Your task is to find the smallest range \([start, end]\) such that at least one number from each list is included in the range.
11+
12+
**Key Points:**
13+
1. The range \([start, end]\) is defined as the difference \(end - start\), and you aim to minimize this difference.
14+
2. Each list contributes at least one number to the range.
15+
16+
**Example:**
17+
```plaintext
18+
Input: nums = [[4, 10, 15, 24, 26],
19+
[0, 9, 12, 20],
20+
[5, 18, 22, 30]]
21+
22+
Output: [20, 24]
23+
Explanation:
24+
- The range [20, 24] includes at least one element from each list:
25+
- From the first list: 24
26+
- From the second list: 20
27+
- From the third list: 22
28+
```
29+
30+
31+
32+
#### **Approach:**
33+
34+
We use a **min-heap (priority queue)** to solve this problem efficiently. Here's how it works:
35+
36+
1. **Initialization:**
37+
- Start by adding the first element from each list into the min-heap.
38+
- Track the minimum (`mini`) and maximum (`maxi`) values among the elements in the heap.
39+
40+
2. **Heap Operations:**
41+
- Extract the smallest element (`mini`) from the heap.
42+
- Calculate the range `[mini, maxi]`.
43+
- If this range is smaller than the previously recorded range, update it.
44+
45+
3. **Add the Next Element:**
46+
- From the same list as the extracted element, add the next element to the heap.
47+
- Update the value of `maxi` if the new element is larger.
48+
49+
4. **Termination:**
50+
- Stop when any list is exhausted, as we can no longer include an element from every list.
51+
52+
## Problem Solution
53+
```cpp
54+
class Node {
55+
public:
56+
int data;
57+
int row;
58+
int col;
59+
60+
Node(int data, int row, int col) {
61+
this->data = data;
62+
this->row = row;
63+
this->col = col;
64+
}
65+
};
66+
67+
class compare{
68+
public:
69+
bool operator()(Node* a, Node* b){
70+
return a -> data > b -> data;
71+
}
72+
};
73+
class Solution {
74+
public:
75+
vector<int> smallestRange(vector<vector<int>>& nums) {
76+
int k = nums.size();
77+
78+
priority_queue<Node*, vector<Node*>, compare> pq;
79+
80+
int mini = INT_MAX;
81+
int maxi = INT_MIN;
82+
83+
for(int i = 0; i < k; i++){
84+
int element = nums[i][0];
85+
86+
maxi = max(maxi, element);
87+
mini = min(mini, element);
88+
89+
pq.push(new Node(element, i, 0));
90+
}
91+
92+
int start = mini;
93+
int end = maxi;
94+
95+
while(!pq.empty()){
96+
Node* temp = pq.top();
97+
pq.pop();
98+
99+
mini = temp -> data;
100+
101+
if(maxi - mini < end - start){
102+
start = mini;
103+
end = maxi;
104+
}
105+
106+
if(temp -> col + 1 < nums[temp -> row].size()){
107+
int nextElement = nums[temp -> row][temp -> col + 1];
108+
109+
maxi = max(nextElement, maxi);
110+
pq.push(new Node(nextElement, temp -> row, temp -> col + 1));
111+
}else{
112+
break;
113+
}
114+
}
115+
116+
return {start, end};
117+
}
118+
};
119+
120+
```
121+
122+
## Problem Solution Explanation
123+
124+
1. **Node Class:**
125+
```cpp
126+
class Node {
127+
public:
128+
int data;
129+
int row;
130+
int col;
131+
132+
Node(int data, int row, int col) {
133+
this->data = data;
134+
this->row = row;
135+
this->col = col;
136+
}
137+
};
138+
```
139+
- The `Node` class stores information about an element:
140+
- `data`: The value of the element.
141+
- `row`: The index of the list (row) to which the element belongs.
142+
- `col`: The index of the element within its list (column).
143+
144+
2. **Custom Comparator:**
145+
```cpp
146+
class compare {
147+
public:
148+
bool operator()(Node* a, Node* b) {
149+
return a->data > b->data;
150+
}
151+
};
152+
```
153+
- This comparator ensures the heap functions as a **min-heap**, meaning the smallest element is at the top.
154+
155+
3. **Priority Queue Declaration:**
156+
```cpp
157+
priority_queue<Node*, vector<Node*>, compare> pq;
158+
```
159+
- A min-heap (`pq`) to store nodes representing the smallest elements from the lists.
160+
161+
4. **Initialize `mini` and `maxi`:**
162+
```cpp
163+
int mini = INT_MAX;
164+
int maxi = INT_MIN;
165+
```
166+
- `mini`: Tracks the smallest value in the current range.
167+
- `maxi`: Tracks the largest value in the current range.
168+
169+
5. **Add First Elements to the Heap:**
170+
```cpp
171+
for (int i = 0; i < k; i++) {
172+
int element = nums[i][0];
173+
maxi = max(maxi, element);
174+
mini = min(mini, element);
175+
pq.push(new Node(element, i, 0));
176+
}
177+
```
178+
- Add the first element of each list to the heap.
179+
- Update `mini` and `maxi` based on these elements.
180+
181+
6. **Initialize the Range:**
182+
```cpp
183+
int start = mini;
184+
int end = maxi;
185+
```
186+
- The range \([start, end]\) is initialized using the smallest and largest elements.
187+
188+
7. **Process the Heap:**
189+
```cpp
190+
while (!pq.empty()) {
191+
Node* temp = pq.top();
192+
pq.pop();
193+
mini = temp->data;
194+
195+
if (maxi - mini < end - start) {
196+
start = mini;
197+
end = maxi;
198+
}
199+
200+
if (temp->col + 1 < nums[temp->row].size()) {
201+
int nextElement = nums[temp->row][temp->col + 1];
202+
maxi = max(nextElement, maxi);
203+
pq.push(new Node(nextElement, temp->row, temp->col + 1));
204+
} else {
205+
break;
206+
}
207+
}
208+
```
209+
- Extract the smallest element (`mini`) from the heap.
210+
- Check if the range `[mini, maxi]` is smaller than the current `[start, end]`.
211+
- Add the next element from the same list to the heap if available. Update `maxi` as needed.
212+
213+
8. **Return the Result:**
214+
```cpp
215+
return {start, end};
216+
```
217+
- Return the smallest range `[start, end]`.
218+
219+
220+
221+
### Step 3: Examples and Explanation
222+
223+
#### Example 1:
224+
```plaintext
225+
Input: nums = [[4, 10, 15, 24, 26],
226+
[0, 9, 12, 20],
227+
[5, 18, 22, 30]]
228+
229+
Output: [20, 24]
230+
```
231+
232+
**Execution Steps:**
233+
1. Add the first elements: `[4, 0, 5]`, `mini = 0`, `maxi = 5`.
234+
2. Extract `mini = 0`, add 9: `[4, 5, 9]`, `maxi = 9`.
235+
3. Extract `mini = 4`, add 10: `[5, 9, 10]`, `maxi = 10`.
236+
4. Extract `mini = 5`, add 18: `[9, 10, 18]`, `maxi = 18`.
237+
5. Extract `mini = 9`, add 12: `[10, 12, 18]`, `maxi = 18`.
238+
6. Extract `mini = 10`, add 15: `[12, 15, 18]`, `maxi = 18`.
239+
7. Extract `mini = 12`, add 20: `[15, 18, 20]`, `maxi = 20`.
240+
8. Extract `mini = 15`, add 24: `[18, 20, 24]`, `maxi = 24`.
241+
9. Extract `mini = 18`, add 22: `[20, 22, 24]`, `maxi = 24`.
242+
10. Extract `mini = 20`. Update range to `[20, 24]`.
243+
244+
245+
246+
### Step 4: Time and Space Complexity
247+
248+
#### **Time Complexity:**
249+
- **Heap Operations:** Each insertion and deletion in the heap takes \(O(\log k)\), where \(k\) is the number of lists.
250+
- **Total Elements Processed:** Each list contributes \(n\) elements, so \(n \times k\) elements are processed.
251+
- **Overall Complexity:** \(O(n \times k \times \log k)\).
252+
253+
#### **Space Complexity:**
254+
- The heap stores at most \(k\) elements at any time: \(O(k)\).
255+
- Additional space for the `Node` objects: \(O(k)\).
256+
- **Overall Complexity:** \(O(k)\).
257+
258+
259+
260+
### Step 5: Recommendations for Students
261+
262+
1. **Practice Heap Problems:**
263+
- Familiarize yourself with heap operations and custom comparators.
264+
265+
2. **Debugging Tip:**
266+
- Print the contents of the heap during each iteration to visualize the algorithm’s progression.
267+
268+
3. **Edge Cases:**
269+
- Test with edge cases like:
270+
- Single-element lists.
271+
- Lists of unequal lengths.
272+
273+
By solving such problems, you'll develop a deeper understanding of advanced data structures and their applications!

0 commit comments

Comments
 (0)