-
Notifications
You must be signed in to change notification settings - Fork 43
/
maximum-number-of-events-that-can-be-attended.py
258 lines (224 loc) · 8.33 KB
/
maximum-number-of-events-that-can-be-attended.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
"""
1353. Maximum Number of Events That Can Be Attended
Medium
You are given an array of events where events[i] = [startDayi, endDayi]. Every event i starts at startDayi and ends at endDayi.
You can attend an event i at any day d where startTimei <= d <= endTimei. You can only attend one event at any time d.
Return the maximum number of events you can attend.
Example 1:
Input: events = [[1,2],[2,3],[3,4]]
Output: 3
Explanation: You can attend all the three events.
One way to attend them all is as shown.
Attend the first event on day 1.
Attend the second event on day 2.
Attend the third event on day 3.
Example 2:
Input: events= [[1,2],[2,3],[3,4],[1,2]]
Output: 4
Constraints:
1 <= events.length <= 105
events[i].length == 2
1 <= startDayi <= endDayi <= 1053
"""
# V0
# IDEA : PRIORITY QUEUE
# NOTE !!!
# We just need to attend d where startTimei <= d <= endTimei, then we CAN attend the meeting
# startTimei <= d <= endTimei. You can only attend one event at any time d.
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
# algorithm: greedy+heap
# step1: loop from min to max day
# step2: each iteration put the candidates in the heap
# step3: each iteration eliminate the ineligibility ones from the heap
# step4: each iteration choose one event attend if it is possible
# time complexity: O(max(n1logn1, n2))
# space complexity: O(n1)
events.sort(key = lambda x: -x[0])
h = []
ans = 0
minDay = 1 #events[-1][0]
maxDay = 100001 #max(x[1] for x in events) + 1
for day in range(minDay, maxDay):
# add all days that can start today
while events and events[-1][0] <= day:
heapq.heappush(h, events.pop()[1])
# remove all days that cannot start
while h and h[0]<day:
heapq.heappop(h)
# if can attend meeting
if h:
heapq.heappop(h)
ans += 1
return ans
# V0'
# IDEA : PRIORITY QUEUE
# NOTE !!!
# We just need to attend d where startTimei <= d <= endTimei, then we CAN attend the meeting
# startTimei <= d <= endTimei. You can only attend one event at any time d.
class Solution:
def maxEvents(self, events):
events.sort(key = lambda x: (-x[0], -x[1]))
endday = []
ans = 0
for day in range(1, 100001, 1):
# check if events is not null and events start day = day (events[-1][0] == day)
# if above conditions are True, we insert "events.pop()[1]" to endday
while events and events[-1][0] == day:
heapq.heappush(endday, events.pop()[1])
# check if endday is not null, if first day in endday < day, then we pop its element
while endday and endday[0] < day:
heapq.heappop(endday)
# if there is still remaining elements in endday -> means we CAN atten the meeting, so ans += 1
if endday:
ans += 1
heapq.heappop(endday)
return ans
# V1
# IDEA : PRIORITY QUEUE
# https://blog.csdn.net/qq_42791848/article/details/109575370
class Solution:
def maxEvents(self, events):
events.sort(key = lambda x: (-x[0], -x[1]))
endday = []
ans = 0
for day in range(1, 100001, 1):
while events and events[-1][0] == day:
heapq.heappush(endday, events.pop()[1])
while endday and endday[0] < day:
heapq.heappop(endday)
if endday:
ans += 1
heapq.heappop(endday)
return ans
# V1''
# IDEA : PRIORITY QUEUE
# https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended/discuss/510263/JavaC%2B%2BPython-Priority-Queue
# IDEA :
# Sort events increased by start time.
# Priority queue pq keeps the current open events.
# Iterate from the day 1 to day 100000,
# Each day, we add new events starting on day d to the queue pq.
# Also we remove the events that are already closed.
# Then we greedily attend the event that ends soonest.
# If we can attend a meeting, we increment the result res.
#
# Complexity
# Time O(d + nlogn), where D is the range of A[i][1]
# Space O(N)
class Solution(object):
def maxEvents(self, A):
# both of below work
#A.sort(reverse=True)
A.sort(key = lambda x : (-x[0], -x[1]))
h = []
res = d = 0
while A or h:
if not h:
d = A[-1][0]
while A and A[-1][0] <= d:
heapq.heappush(h, A.pop()[1])
heapq.heappop(h)
res += 1
d += 1
while h and h[0] < d:
heapq.heappop(h)
return res
# V1''''
# IDEA : HEAP
# https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended/discuss/1799845/Python-Heap
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
events.sort()
heap = []
n = max(events, key=lambda x: x[1])[1]
cnt = 0
i = 0
for day in range(1, n+1):
while i < len(events) and events[i][0] == day:
heappush(heap, events[i][1])
i += 1
while heap and heap[0] < day:
heappop(heap)
if heap:
curr = heappop(heap)
cnt += 1
return cnt
# V1'''''
# IDEA : HEAP + GREEDY
# https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended/discuss/1414435/Python-Greedy%2BHeap
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
# algorithm: greedy+heap
# step1: loop from min to max day
# step2: each iteration put the candidates in the heap
# step3: each iteration eliminate the ineligibility ones from the heap
# step4: each iteration choose one event attend if it is possible
# time complexity: O(max(n1logn1, n2))
# space complexity: O(n1)
events.sort(key = lambda x: -x[0])
h = []
att = 0
minDay, maxDay = events[-1][0], max(events, key=lambda x:x[1])[1]+1
for day in range(minDay, maxDay):
# add all days that can start today
while events and events[-1][0]<=day:
heapq.heappush(h, events.pop()[1])
# remove all days that cannot start
while h and h[0]<day:
heapq.heappop(h)
# attend
if h:
heapq.heappop(h)
att += 1
return att
# V1''''''
# IDEA : HEAP + index
# https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended/discuss/954460/Python%3A-faster-than-79.04-of-Python
import heapq
class Solution:
def maxEvents(self, events: List[List[int]]) -> int:
eventsIndex: Dict[int, List[List[int]] ] = {}
for e in events:
if e[0] not in eventsIndex:
eventsIndex[e[0]] = [e]
else:
eventsIndex[e[0]].append(e)
firstDay = min(events)[0]
lastDay = max(events, key=lambda x: x[1])[1]
eventCounter = 0
candidates = [] # куча с приоритетом по дню завершения события
for d in range(firstDay, lastDay+1):
if d in eventsIndex:
for e in eventsIndex[d]:
heapq.heappush(candidates, e[1])
if candidates:
heapq.heappop(candidates)
eventCounter = eventCounter + 1
while candidates and (candidates[0] <= d):
heapq.heappop(candidates)
return eventCounter
# V1'''''
# https://www.youtube.com/watch?v=NjF9JGDGxg8
# https://zxi.mytechroad.com/blog/greedy/leetcode-1353-maximum-number-of-events-that-can-be-attended/
# C++
# class Solution {
# public:
# int maxEvents(vector<vector<int>>& events) {
# sort(begin(events), end(events), [](const auto& a, const auto& b){
# return a[1] < b[1];
# });
# int ans = 0;
# int seen[100001] = {0};
# for (const auto& e : events) {
# for (int i = e[0]; i <= e[1]; ++i) {
# if (seen[i]) continue;
# ++seen[i];
# ++ans;
# break;
# }
# }
# return ans;
# }
# };
# V2