Skip to content

Commit 0b50a50

Browse files
authored
Create README.md
1 parent 2eec520 commit 0b50a50

File tree

1 file changed

+332
-0
lines changed
  • 25 - Greedy Algorithm Problems/01 - N Meetings in One Room

1 file changed

+332
-0
lines changed
Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
<h1 align="center">N - Meetings in - One Room</h1>
2+
3+
## Problem Statement
4+
5+
**Problem URL :** [N Meetings in One Room](https://www.geeksforgeeks.org/problems/n-meetings-in-one-room-1587115620/1)
6+
7+
![image](https://github.com/user-attachments/assets/c046bdf9-fa02-40a8-8883-074b6e62c82b)
8+
9+
### Problem Explanation
10+
You are given ( N ) meetings with their **start times** and **end times**. You must schedule these meetings in a single room such that the maximum number of meetings can take place without any overlap.
11+
12+
### **Constraints:**
13+
1. A meeting can only start after the previous one ends.
14+
2. The room can only host one meeting at a time.
15+
16+
### **Objective:**
17+
Find the **maximum number of non-overlapping meetings** that can be conducted.
18+
19+
### **Input Format:**
20+
- ( N ): Number of meetings.
21+
- Two arrays:
22+
- `start[]`: An array where each element represents the start time of a meeting.
23+
- `end[]`: An array where each element represents the end time of a meeting.
24+
25+
### **Output Format:**
26+
The maximum number of meetings that can be conducted.
27+
28+
### **Example:**
29+
30+
#### **Input:**
31+
- ( N = 6 )
32+
- `start[] = [1, 3, 0, 5, 8, 5]`
33+
- `end[] = [2, 4, 6, 7, 9, 9]`
34+
35+
#### **Output:**
36+
4
37+
38+
#### **Explanation:**
39+
You can schedule the following 4 meetings:
40+
- Meeting 1: Starts at 1 and ends at 2.
41+
- Meeting 2: Starts at 3 and ends at 4.
42+
- Meeting 4: Starts at 5 and ends at 7.
43+
- Meeting 5: Starts at 8 and ends at 9.
44+
45+
### **Greedy Algorithm Approach**
46+
47+
The problem is to find the **maximum number of non-overlapping meetings** that can be scheduled in one room. The **greedy approach** involves always making the most optimal choice at each step to ensure the maximum number of meetings can fit without overlapping.
48+
1. **Sort Meetings by End Time**:
49+
- Sort all meetings based on their ending times.
50+
- **Why?**
51+
- The meeting that ends the earliest leaves the room free for subsequent meetings sooner.
52+
- This maximizes the number of meetings we can schedule.
53+
- **Example**:
54+
```cpp
55+
start = [1, 3, 0, 5, 8, 5];
56+
end = [2, 4, 6, 7, 9, 9];
57+
```
58+
After pairing and sorting by end times:
59+
```
60+
Meetings: [(1, 2), (3, 4), (5, 7), (0, 6), (8, 9), (5, 9)]
61+
```
62+
63+
2. **Select the First Meeting**:
64+
- Always select the first meeting after sorting since it has the earliest ending time.
65+
- **Example**:
66+
- First meeting: `(1, 2)` → Selected.
67+
- The room is now booked until time `2`.
68+
69+
3. **Iterate and Select Non-Overlapping Meetings**:
70+
- Traverse through the sorted meetings and select a meeting only if its **start time** is after the **end time** of the last selected meeting.
71+
- **Why?**
72+
- This ensures no overlap, allowing us to include as many meetings as possible.
73+
- **Example** (Continuing from Step 2):
74+
- Next meeting `(3, 4)` → `3 > 2` → Selected. Room now booked until `4`.
75+
- Next meeting `(5, 7)` → `5 > 4` → Selected. Room now booked until `7`.
76+
- Next meeting `(0, 6)` → `0 < 7` → Skipped (overlaps).
77+
- Next meeting `(8, 9)` → `8 > 7` → Selected. Room now booked until `9`.
78+
- Next meeting `(5, 9)` → `5 < 9` → Skipped (overlaps).
79+
80+
4. **Return the Count**:
81+
- The total number of meetings selected is the maximum number of non-overlapping meetings that can be scheduled.
82+
- **Example Result**: `4`.
83+
84+
### **Detailed Example**
85+
86+
#### **Input**:
87+
```cpp
88+
start = [1, 3, 0, 5, 8, 5];
89+
end = [2, 4, 6, 7, 9, 9];
90+
```
91+
92+
#### **Step 1: Pair and Sort by End Times**:
93+
- Pair the meetings: `[(1, 2), (3, 4), (0, 6), (5, 7), (8, 9), (5, 9)]`.
94+
- Sort by end time:
95+
```
96+
[(1, 2), (3, 4), (5, 7), (0, 6), (8, 9), (5, 9)]
97+
```
98+
99+
#### **Step 2: Initialize**:
100+
- Select the first meeting: `(1, 2)` → Count = 1, `ansEnd = 2`.
101+
102+
#### **Step 3: Traverse and Select**:
103+
- **Meeting (3, 4)**:
104+
- `3 > 2` → Selected.
105+
- Count = 2, `ansEnd = 4`.
106+
- **Meeting (5, 7)**:
107+
- `5 > 4` → Selected.
108+
- Count = 3, `ansEnd = 7`.
109+
- **Meeting (0, 6)**:
110+
- `0 < 7` → Skipped (overlaps).
111+
- **Meeting (8, 9)**:
112+
- `8 > 7` → Selected.
113+
- Count = 4, `ansEnd = 9`.
114+
- **Meeting (5, 9)**:
115+
- `5 < 9` → Skipped (overlaps).
116+
117+
#### **Step 4: Return Result**:
118+
- Maximum number of meetings = `4`.
119+
120+
121+
### **Why the Greedy Approach Works**
122+
123+
1. **Optimal Substructure**:
124+
- The problem can be divided into smaller subproblems, where selecting the earliest finishing meeting is the best choice for maximizing the remaining time.
125+
126+
2. **No Overlap**:
127+
- By ensuring no overlap through the condition `start > ansEnd`, the algorithm guarantees that each meeting selected is valid.
128+
129+
3. **Locally Optimal Choices → Globally Optimal Solution**:
130+
- Sorting by end time and selecting the earliest available meeting ensures the global maximum number of meetings.
131+
132+
## Problem Solution
133+
```cpp
134+
class Solution {
135+
public:
136+
137+
// Function to find the maximum number of meetings that can be scheduled
138+
int maxMeetings(vector<int>& start, vector<int>& end) {
139+
int n = start.size(); // Get the number of meetings
140+
141+
// Vector to store pairs of (start time, end time) for each meeting
142+
vector<pair<int, int>> v;
143+
144+
// Populate the vector with pairs of start and end times
145+
for(int i = 0; i < n; i++) {
146+
pair<int, int> p = make_pair(start[i], end[i]); // Create a pair of start and end time
147+
v.push_back(p); // Add the pair to the vector
148+
}
149+
150+
// Sort the meetings based on their end times
151+
sort(v.begin(), v.end(), [](pair<int, int> a, pair<int, int> b) {
152+
return a.second < b.second; // Sort by the second element (end time) of the pair
153+
});
154+
155+
// Initialize count of selected meetings and set the end time of the first meeting
156+
int count = 1; // The first meeting is always selected
157+
int ansEnd = v[0].second; // Set the end time of the first meeting
158+
159+
// Iterate through the remaining meetings
160+
for(int i = 1; i < n; i++) {
161+
// If the start time of the current meeting is greater than the end time of the last selected meeting
162+
if(v[i].first > ansEnd) {
163+
count++; // Increment the count of selected meetings
164+
ansEnd = v[i].second; // Update the end time to the current meeting's end time
165+
}
166+
}
167+
168+
// Return the maximum number of non-overlapping meetings
169+
return count;
170+
}
171+
};
172+
```
173+
174+
## Problem Solution Explanation
175+
176+
```cpp
177+
class Solution {
178+
public:
179+
```
180+
- A class named `Solution` is created with public access specifier to hold the function `maxMeetings`.
181+
182+
183+
```cpp
184+
int maxMeetings(vector<int>& start, vector<int>& end) {
185+
```
186+
- `maxMeetings` is a member function that takes two vectors as input:
187+
- `start`: Contains the start times of the meetings.
188+
- `end`: Contains the end times of the meetings.
189+
- **Purpose**: To find the maximum number of non-overlapping meetings that can be attended.
190+
191+
**Example Input**:
192+
```cpp
193+
start = [1, 3, 0, 5, 8, 5];
194+
end = [2, 4, 6, 7, 9, 9];
195+
```
196+
197+
198+
```cpp
199+
int n = start.size();
200+
```
201+
- The variable `n` holds the number of meetings, which is the size of the `start` vector.
202+
- For the given example, `n = 6`.
203+
204+
205+
```cpp
206+
vector<pair<int, int>> v;
207+
```
208+
- A vector `v` is declared to store pairs of `(start, end)` times for the meetings.
209+
- **Purpose**: To manage meetings as pairs for easier sorting and processing.
210+
211+
212+
```cpp
213+
for(int i = 0; i < n; i++) {
214+
pair<int, int> p = make_pair(start[i], end[i]);
215+
v.push_back(p);
216+
}
217+
```
218+
- **What Happens**:
219+
- Iterates through all meetings.
220+
- Creates a pair of `start` and `end` times using `make_pair`.
221+
- Adds the pair to the vector `v`.
222+
- **Result for Example**:
223+
- After this loop, `v = [(1, 2), (3, 4), (0, 6), (5, 7), (8, 9), (5, 9)]`.
224+
225+
226+
```cpp
227+
sort(v.begin(), v.end(), [](pair<int, int> a, pair<int, int> b) {
228+
return a.second < b.second;
229+
});
230+
```
231+
- The `sort` function sorts the meetings in `v` by their **end times** (second element of each pair).
232+
- **Custom Comparator**:
233+
- Lambda function compares two pairs and sorts them by `end` time.
234+
- **Result for Example**:
235+
- After sorting: `v = [(1, 2), (3, 4), (5, 7), (0, 6), (8, 9), (5, 9)]`.
236+
237+
238+
```cpp
239+
int count = 1;
240+
int ansEnd = v[0].second;
241+
```
242+
- Initializes:
243+
- `count` to 1: Assumes the first meeting is always selected.
244+
- `ansEnd` to the end time of the first meeting: Tracks the end time of the last selected meeting.
245+
- **After Initialization**:
246+
- `count = 1`.
247+
- `ansEnd = 2`.
248+
249+
250+
```cpp
251+
for(int i = 1; i < n; i++) {
252+
if(v[i].first > ansEnd) {
253+
count++;
254+
ansEnd = v[i].second;
255+
}
256+
}
257+
```
258+
- Iterates through all meetings starting from the second meeting.
259+
- **Condition**: Checks if the `start` time of the current meeting (`v[i].first`) is greater than the `ansEnd` (end time of the last selected meeting).
260+
- If true, selects the meeting:
261+
- Increments `count`.
262+
- Updates `ansEnd` to the current meeting’s `end` time.
263+
264+
**Step-by-Step Execution** for Example:
265+
- **Iteration 1** (`i = 1`):
266+
- Meeting: `(3, 4)`.
267+
- Condition: `3 > 2` (True).
268+
- Select the meeting. Update `count = 2`, `ansEnd = 4`.
269+
- **Iteration 2** (`i = 2`):
270+
- Meeting: `(5, 7)`.
271+
- Condition: `5 > 4` (True).
272+
- Select the meeting. Update `count = 3`, `ansEnd = 7`.
273+
- **Iteration 3** (`i = 3`):
274+
- Meeting: `(0, 6)`.
275+
- Condition: `0 > 7` (False).
276+
- Skip the meeting.
277+
- **Iteration 4** (`i = 4`):
278+
- Meeting: `(8, 9)`.
279+
- Condition: `8 > 7` (True).
280+
- Select the meeting. Update `count = 4`, `ansEnd = 9`.
281+
- **Iteration 5** (`i = 5`):
282+
- Meeting: `(5, 9)`.
283+
- Condition: `5 > 9` (False).
284+
- Skip the meeting.
285+
286+
287+
```cpp
288+
return count;
289+
```
290+
- Returns the total number of selected meetings.
291+
- **For Example Input**: `count = 4`.
292+
293+
294+
### **Detailed Example Output**
295+
296+
**Input**:
297+
```cpp
298+
start = [1, 3, 0, 5, 8, 5];
299+
end = [2, 4, 6, 7, 9, 9];
300+
```
301+
302+
**Step-by-Step Execution**:
303+
1. Pair the meetings: `[(1, 2), (3, 4), (0, 6), (5, 7), (8, 9), (5, 9)]`.
304+
2. Sort by end time: `[(1, 2), (3, 4), (5, 7), (0, 6), (8, 9), (5, 9)]`.
305+
3. Select meetings:
306+
- Meeting `(1, 2)` → Selected.
307+
- Meeting `(3, 4)` → Selected.
308+
- Meeting `(5, 7)` → Selected.
309+
- Meeting `(8, 9)` → Selected.
310+
311+
**Output**:
312+
```cpp
313+
4
314+
```
315+
316+
### **Time Complexity**
317+
1. **Pair Creation**:
318+
- O(n): Populating the vector with `n` pairs.
319+
2. **Sorting**:
320+
- O(n log n): Sorting the vector of `n` pairs by their end times.
321+
3. **Iteration**:
322+
- O(n): Iterating through the meetings to count non-overlapping ones.
323+
324+
**Total**: **O(n log n)** (dominated by sorting).
325+
326+
### **Space Complexity**
327+
1. **Vector `v`**:
328+
- Stores `n` pairs, requiring O(n) space.
329+
2. **Auxiliary Space for Sorting**:
330+
- Depends on the sorting algorithm but typically O(log n).
331+
332+
**Total**: **O(n)**.

0 commit comments

Comments
 (0)