@@ -68,13 +68,17 @@ tags:
68
68
69
69
### 方法一:哈希表 + 贪心 + 优先队列
70
70
71
- 定义哈希表记录每个会议的开始和结束时间,其中键为会议开始时间,值为结束时间列表 。
71
+ 我们用一个哈希表 $\textit{g}$ 记录每个会议的开始和结束时间。键为会议的开始时间,值为一个列表,包含所有在该开始时间开始的会议的结束时间。用两个变量 $\textit{l}$ 和 $\textit{r}$ 分别记录会议的最小开始时间和最大结束时间 。
72
72
73
- 枚举当前时间 $ s$,找出所有开始时间等于当前时间的会议,将其结束时间加入优先队列(小根堆)中。同时,优先队列要移除所有结束时间小于当前时间的会议。
73
+ 对于从小到大每个在 $\textit{l}$ 到 $\textit{r}$ 的时间点 $ s$,我们需要做以下操作:
74
74
75
- 然后从优先队列中取出结束时间最小的会议,即为当前时间可以参加的会议,累加答案数。如果优先队列为空,则说明当前时间没有可以参加的会议。
75
+ 1 . 从优先队列中移除所有结束时间小于当前时间 $s$ 的会议。
76
+ 2 . 将所有开始时间等于当前时间 $s$ 的会议的结束时间加入优先队列中。
77
+ 3 . 如果优先队列不为空,则取出结束时间最小的会议,累加答案数,并从优先队列中移除该会议。
76
78
77
- 时间复杂度 $O(m \times \log n)$,空间复杂度 $O(n)$。其中 $m$, $n$ 分别表示会议的最大结束时间,以及会议的数量。
79
+ 这样,我们可以确保在每个时间点 $s$,我们都能参加结束时间最早的会议,从而最大化参加的会议数。
80
+
81
+ 时间复杂度 $O(M \times \log n)$,空间复杂度 $O(n)$,其中 $M$ 和 $n$ 分别为会议的最大结束时间和会议的数量。
78
82
79
83
<!-- tabs:start -->
80
84
@@ -83,22 +87,22 @@ tags:
83
87
``` python
84
88
class Solution :
85
89
def maxEvents (self , events : List[List[int ]]) -> int :
86
- d = defaultdict(list )
87
- i, j = inf, 0
90
+ g = defaultdict(list )
91
+ l, r = inf, 0
88
92
for s, e in events:
89
- d [s].append(e)
90
- i = min (i , s)
91
- j = max (j , e)
92
- h = []
93
+ g [s].append(e)
94
+ l = min (l , s)
95
+ r = max (r , e)
96
+ pq = []
93
97
ans = 0
94
- for s in range (i, j + 1 ):
95
- while h and h[0 ] < s:
96
- heappop(h)
97
- for e in d[s]:
98
- heappush(h, e)
99
- if h:
98
+ for s in range (l, r + 1 ):
99
+ while pq and pq[0 ] < s:
100
+ heappop(pq)
101
+ for e in g[s]:
102
+ heappush(pq, e)
103
+ if pq:
104
+ heappop(pq)
100
105
ans += 1
101
- heappop(h)
102
106
return ans
103
107
```
104
108
@@ -107,26 +111,26 @@ class Solution:
107
111
``` java
108
112
class Solution {
109
113
public int maxEvents (int [][] events ) {
110
- Map<Integer , List<Integer > > d = new HashMap<> ();
111
- int i = Integer . MAX_VALUE , j = 0 ;
112
- for (var v : events) {
113
- int s = v [0 ], e = v [1 ];
114
- d . computeIfAbsent(s, k - > new ArrayList<> ()). add(e);
115
- i = Math . min(i , s);
116
- j = Math . max(j , e);
114
+ Map<Integer , List<Integer > > g = new HashMap<> ();
115
+ int l = Integer . MAX_VALUE , r = 0 ;
116
+ for (int [] event : events) {
117
+ int s = event [0 ], e = event [1 ];
118
+ g . computeIfAbsent(s, k - > new ArrayList<> ()). add(e);
119
+ l = Math . min(l , s);
120
+ r = Math . max(r , e);
117
121
}
118
- PriorityQueue<Integer > q = new PriorityQueue<> ();
122
+ PriorityQueue<Integer > pq = new PriorityQueue<> ();
119
123
int ans = 0 ;
120
- for (int s = i ; s <= j; ++ s ) {
121
- while (! q . isEmpty() && q . peek() < s) {
122
- q . poll();
124
+ for (int s = l ; s <= r; s ++ ) {
125
+ while (! pq . isEmpty() && pq . peek() < s) {
126
+ pq . poll();
123
127
}
124
- for (int e : d . getOrDefault(s, Collections . emptyList ())) {
125
- q . offer(e);
128
+ for (int e : g . getOrDefault(s, List . of ())) {
129
+ pq . offer(e);
126
130
}
127
- if (! q . isEmpty()) {
128
- q . poll();
129
- ++ ans ;
131
+ if (! pq . isEmpty()) {
132
+ pq . poll();
133
+ ans ++ ;
130
134
}
131
135
}
132
136
return ans;
@@ -140,26 +144,26 @@ class Solution {
140
144
class Solution {
141
145
public:
142
146
int maxEvents(vector<vector<int >>& events) {
143
- unordered_map<int, vector<int >> d ;
144
- int i = INT_MAX, j = 0;
145
- for (auto& v : events) {
146
- int s = v [ 0] , e = v [ 1] ;
147
- d [ s] .push_back(e);
148
- i = min(i , s);
149
- j = max(j , e);
147
+ unordered_map<int, vector<int >> g ;
148
+ int l = INT_MAX, r = 0;
149
+ for (auto& event : events) {
150
+ int s = event [ 0] , e = event [ 1] ;
151
+ g [ s] .push_back(e);
152
+ l = min(l , s);
153
+ r = max(r , e);
150
154
}
151
- priority_queue<int, vector<int >, greater<int >> q ;
155
+ priority_queue<int, vector<int >, greater<int >> pq ;
152
156
int ans = 0;
153
- for (int s = i ; s <= j ; ++s) {
154
- while (q.size () && q .top() < s) {
155
- q .pop();
157
+ for (int s = l ; s <= r ; ++s) {
158
+ while (!pq.empty () && pq .top() < s) {
159
+ pq .pop();
156
160
}
157
- for (int e : d [ s] ) {
158
- q .push(e);
161
+ for (int e : g [ s] ) {
162
+ pq .push(e);
159
163
}
160
- if (q.size()) {
164
+ if (!pq.empty()) {
165
+ pq.pop();
161
166
++ans;
162
- q.pop();
163
167
}
164
168
}
165
169
return ans;
@@ -170,44 +174,123 @@ public:
170
174
#### Go
171
175
172
176
```go
173
- func maxEvents(events [][]int) int {
174
- d := map[int][]int{}
175
- i, j := math.MaxInt32, 0
176
- for _, v := range events {
177
- s, e := v [0], v [1]
178
- d [s] = append(d [s], e)
179
- i = min(i , s)
180
- j = max(j , e)
177
+ func maxEvents(events [][]int) (ans int) {
178
+ g := map[int][]int{}
179
+ l, r := math.MaxInt32, 0
180
+ for _, event := range events {
181
+ s, e := event [0], event [1]
182
+ g [s] = append(g [s], e)
183
+ l = min(l , s)
184
+ r = max(r , e)
181
185
}
182
- q := hp{}
183
- ans := 0
184
- for s := i; s <= j; s++ {
185
- for q.Len() > 0 && q.IntSlice[0] < s {
186
- heap.Pop(&q)
186
+
187
+ pq := &hp{}
188
+ heap.Init(pq)
189
+ for s := l; s <= r; s++ {
190
+ for pq.Len() > 0 && pq.IntSlice[0] < s {
191
+ heap.Pop(pq)
187
192
}
188
- for _, e := range d [s] {
189
- heap.Push(&q , e)
193
+ for _, e := range g [s] {
194
+ heap.Push(pq , e)
190
195
}
191
- if q .Len() > 0 {
192
- heap.Pop(&q )
196
+ if pq .Len() > 0 {
197
+ heap.Pop(pq )
193
198
ans++
194
199
}
195
200
}
196
- return ans
201
+ return
197
202
}
198
203
199
204
type hp struct{ sort.IntSlice }
200
205
201
206
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
202
207
func (h *hp) Pop() any {
203
- a := h.IntSlice
204
- v := a[len(a) -1]
205
- h.IntSlice = a[:len(a) -1]
208
+ n := len( h.IntSlice)
209
+ v := h.IntSlice[n -1]
210
+ h.IntSlice = h.IntSlice[:n -1]
206
211
return v
207
212
}
208
213
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
209
214
```
210
215
216
+ #### TypeScript
217
+
218
+ ``` ts
219
+ function maxEvents(events : number [][]): number {
220
+ const g: Map <number , number []> = new Map ();
221
+ let l = Infinity ,
222
+ r = 0 ;
223
+ for (const [s, e] of events ) {
224
+ if (! g .has (s )) g .set (s , []);
225
+ g .get (s )! .push (e );
226
+ l = Math .min (l , s );
227
+ r = Math .max (r , e );
228
+ }
229
+
230
+ const pq = new MinPriorityQueue <number >();
231
+ let ans = 0 ;
232
+ for (let s = l ; s <= r ; s ++ ) {
233
+ while (! pq .isEmpty () && pq .front () < s ) {
234
+ pq .dequeue ();
235
+ }
236
+ for (const e of g .get (s ) || []) {
237
+ pq .enqueue (e );
238
+ }
239
+ if (! pq .isEmpty ()) {
240
+ pq .dequeue ();
241
+ ans ++ ;
242
+ }
243
+ }
244
+ return ans ;
245
+ }
246
+ ```
247
+
248
+ #### Rust
249
+
250
+ ``` rust
251
+ use std :: collections :: {BinaryHeap , HashMap };
252
+ use std :: cmp :: Reverse ;
253
+
254
+ impl Solution {
255
+ pub fn max_events (events : Vec <Vec <i32 >>) -> i32 {
256
+ let mut g : HashMap <i32 , Vec <i32 >> = HashMap :: new ();
257
+ let mut l = i32 :: MAX ;
258
+ let mut r = 0 ;
259
+
260
+ for event in events {
261
+ let s = event [0 ];
262
+ let e = event [1 ];
263
+ g . entry (s ). or_default (). push (e );
264
+ l = l . min (s );
265
+ r = r . max (e );
266
+ }
267
+
268
+ let mut pq = BinaryHeap :: new ();
269
+ let mut ans = 0 ;
270
+
271
+ for s in l ..= r {
272
+ while let Some (& Reverse (top )) = pq . peek () {
273
+ if top < s {
274
+ pq . pop ();
275
+ } else {
276
+ break ;
277
+ }
278
+ }
279
+ if let Some (ends ) = g . get (& s ) {
280
+ for & e in ends {
281
+ pq . push (Reverse (e ));
282
+ }
283
+ }
284
+ if pq . pop (). is_some () {
285
+ ans += 1 ;
286
+ }
287
+ }
288
+
289
+ ans
290
+ }
291
+ }
292
+ ```
293
+
211
294
<!-- tabs: end -->
212
295
213
296
<!-- solution: end -->
0 commit comments