Skip to content

Commit 6635757

Browse files
authored
Create README.md
1 parent 44b5a90 commit 6635757

File tree

1 file changed

+260
-0
lines changed
  • 19 - Heap Data Structure Problems/14 - Smallest Range in K Lists

1 file changed

+260
-0
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
<h1 align='center'>Smallest - Range - in K - Lists</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [Smallest Range in K Lists](https://www.geeksforgeeks.org/problems/find-smallest-range-containing-elements-from-k-lists/1)
6+
7+
![image](https://github.com/user-attachments/assets/c672e8fc-cfc7-459c-8fae-79e5175483ba)
8+
![image](https://github.com/user-attachments/assets/be221229-359a-43ec-8105-d7a030254fa9)
9+
10+
## Problem Explanation
11+
The task is to find the smallest range that includes at least one element from each of the `k` sorted lists (arrays). The range is defined as `[start, end]`, where:
12+
- `start` is the smallest number in the range.
13+
- `end` is the largest number in the range.
14+
15+
**Example:**
16+
```plaintext
17+
Input:
18+
k = 3, n = 5
19+
arr = [[4, 7, 9, 12, 15],
20+
[0, 8, 10, 14, 20],
21+
[6, 12, 16, 30, 50]]
22+
23+
Output:
24+
[6, 8]
25+
Explanation:
26+
- The range `[6, 8]` contains at least one element from each list:
27+
- From the first list: 7
28+
- From the second list: 8
29+
- From the third list: 6
30+
```
31+
32+
33+
34+
#### **Approach:**
35+
We use a **min-heap** (priority queue) to solve this problem. The algorithm works as follows:
36+
37+
1. **Initialization:**
38+
- Start by adding the first element of each list to the min-heap.
39+
- Track the minimum (`mini`) and maximum (`maxi`) values among the elements in the heap.
40+
41+
2. **Range Calculation:**
42+
- The current range is `[mini, maxi]`.
43+
- As we process the heap, check if the current range is smaller than the previous range. If it is, update the range.
44+
45+
3. **Heap Operations:**
46+
- Remove the smallest element (`mini`) from the heap.
47+
- Add the next element from the same list to the heap.
48+
- Update `mini` and `maxi`.
49+
50+
4. **Termination:**
51+
- Stop when any of the lists is exhausted, as we can no longer include an element from every list.
52+
53+
## Problem Solution
54+
```cpp
55+
class Node{
56+
public:
57+
int data;
58+
int row;
59+
int col;
60+
61+
Node(int data, int row, int col){
62+
this -> data = data;
63+
this -> row = row;
64+
this -> col = col;
65+
}
66+
};
67+
68+
class compare{
69+
public:
70+
bool operator()(Node* a, Node* b){
71+
return a -> data > b -> data;
72+
}
73+
};
74+
class Solution{
75+
public:
76+
pair<int,int> findSmallestRange(int arr[][N], int n, int k)
77+
{
78+
int mini = INT_MAX;
79+
int maxi = INT_MIN;
80+
81+
priority_queue<Node*, vector<Node*>, compare> minHeap;
82+
83+
for(int i = 0; i < k; i++){
84+
int element = arr[i][0];
85+
86+
mini = min(mini, element);
87+
maxi = max(maxi, element);
88+
89+
minHeap.push(new Node(element, i, 0));
90+
}
91+
92+
93+
int start = mini, end = maxi;
94+
95+
while(!minHeap.empty()){
96+
Node* temp = minHeap.top();
97+
minHeap.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 < n){
107+
maxi = max(maxi, arr[temp->row][temp->col + 1]);
108+
minHeap.push(new Node(arr[temp->row][temp->col + 1], temp -> row, temp -> col + 1));
109+
}else break;
110+
111+
}
112+
113+
return {start, end};
114+
115+
}
116+
};
117+
```
118+
119+
## Problem Solution Explanation
120+
121+
1. **Node Class:**
122+
```cpp
123+
class Node {
124+
public:
125+
int data;
126+
int row;
127+
int col;
128+
129+
Node(int data, int row, int col) {
130+
this->data = data;
131+
this->row = row;
132+
this->col = col;
133+
}
134+
};
135+
```
136+
- The `Node` class is used to store three pieces of information:
137+
- `data`: The value of the current element.
138+
- `row`: The row index of the element (corresponding to the list it belongs to).
139+
- `col`: The column index of the element in its row.
140+
141+
2. **Custom Comparator:**
142+
```cpp
143+
class compare {
144+
public:
145+
bool operator()(Node* a, Node* b) {
146+
return a->data > b->data;
147+
}
148+
};
149+
```
150+
- This comparator defines the priority for the heap.
151+
- It ensures the heap works as a **min-heap**, with the smallest element at the top.
152+
153+
3. **Initialization:**
154+
```cpp
155+
priority_queue<Node*, vector<Node*>, compare> minHeap;
156+
int mini = INT_MAX;
157+
int maxi = INT_MIN;
158+
```
159+
- `minHeap`: Stores the smallest elements across all lists.
160+
- `mini` and `maxi`: Track the smallest and largest values in the current range.
161+
162+
4. **Push Initial Elements into the Heap:**
163+
```cpp
164+
for (int i = 0; i < k; i++) {
165+
int element = arr[i][0];
166+
mini = min(mini, element);
167+
maxi = max(maxi, element);
168+
minHeap.push(new Node(element, i, 0));
169+
}
170+
```
171+
- For each list, add its first element to the heap.
172+
- Update `mini` and `maxi` to reflect the smallest and largest values.
173+
174+
5. **Track the Best Range:**
175+
```cpp
176+
int start = mini, end = maxi;
177+
```
178+
- Initialize the range `[start, end]` with the initial `mini` and `maxi`.
179+
180+
6. **Process the Min-Heap:**
181+
```cpp
182+
while (!minHeap.empty()) {
183+
Node* temp = minHeap.top();
184+
minHeap.pop();
185+
mini = temp->data;
186+
187+
if (maxi - mini < end - start) {
188+
start = mini;
189+
end = maxi;
190+
}
191+
192+
if (temp->col + 1 < n) {
193+
int nextElement = arr[temp->row][temp->col + 1];
194+
maxi = max(maxi, nextElement);
195+
minHeap.push(new Node(nextElement, temp->row, temp->col + 1));
196+
} else {
197+
break;
198+
}
199+
}
200+
```
201+
- Extract the smallest element (`mini`) from the heap.
202+
- Check if the current range `[mini, maxi]` is smaller than `[start, end]`.
203+
- Add the next element from the same list to the heap, and update `maxi`.
204+
- Stop if any list is exhausted.
205+
206+
7. **Return the Result:**
207+
```cpp
208+
return {start, end};
209+
```
210+
- Return the smallest range `[start, end]`.
211+
212+
213+
214+
### Step 3: Examples and Explanation
215+
216+
#### Example 1:
217+
```plaintext
218+
Input:
219+
k = 3, n = 5
220+
arr = [[4, 7, 9, 12, 15],
221+
[0, 8, 10, 14, 20],
222+
[6, 12, 16, 30, 50]]
223+
224+
Output:
225+
[6, 8]
226+
```
227+
**Execution Steps:**
228+
1. Initialize heap: `[4, 0, 6]`, `mini = 0`, `maxi = 6`.
229+
2. Extract `mini = 0`, add `7` to the heap: `[4, 6, 7]`, `maxi = 7`.
230+
3. Extract `mini = 4`, add `8` to the heap: `[6, 7, 8]`, `maxi = 8`.
231+
4. Extract `mini = 6`, update range `[6, 8]`.
232+
233+
234+
235+
### Step 4: Time and Space Complexity
236+
237+
#### **Time Complexity:**
238+
- **Heap Operations:** Each insertion and deletion in the heap takes \(O(\log k)\), where \(k\) is the number of lists.
239+
- **Total Elements Processed:** \(n \times k\) elements are processed (each list has \(n\) elements).
240+
- **Overall:** \(O(n \times k \times \log k)\).
241+
242+
#### **Space Complexity:**
243+
- The heap stores at most \(k\) elements at any time: \(O(k)\).
244+
- Additional space for the `Node` objects: \(O(k)\).
245+
- **Overall:** \(O(k)\).
246+
247+
248+
249+
### Step 5: Recommendations for Students
250+
1. **Understand the Min-Heap:**
251+
- Practice problems that involve heap data structures to solidify your understanding.
252+
- Implement custom comparators and understand their use cases.
253+
254+
2. **Optimize for Edge Cases:**
255+
- Test with edge cases like single-element lists or lists with duplicate elements.
256+
257+
3. **Debugging Tips:**
258+
- Print the heap contents at each step to debug and understand the flow.
259+
260+
By practicing such problems, you'll develop skills in working with advanced data structures like heaps and improve problem-solving efficiency!

0 commit comments

Comments
 (0)