@@ -101,32 +101,334 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3873.Ma
101101
102102<!-- solution:start -->
103103
104- ### 方法一
104+ ### 方法一:并查集
105+
106+ 我们可以使用并查集来解决这个问题。
107+
108+ 首先,我们将所有点的 $x$ 坐标和 $y$ 坐标进行映射,使得它们在同一个并查集中。具体来说,我们可以将 $y$ 坐标加上一个足够大的常数 $m$(例如 $3 \times 10^9$),以确保 $x$ 和 $y$ 坐标不会发生冲突。
109+
110+ 接下来,我们遍历所有点,将具有相同 $x$ 坐标或 $y$ 坐标的点进行合并。这样,具有相同 $x$ 或 $y$ 坐标的点就会被分到同一个集合中。
111+
112+ 最后,我们统计每个集合中的点数,并找到最大的两个集合的大小。由于我们可以添加一个新的点来连接这两个集合,因此最终的答案就是这两个集合的大小之和再加上 1。
113+
114+ 时间复杂度 $O(n \alpha(n))$,其中 $n$ 是点的数量,而 $\alpha$ 是阿克曼函数的反函数。空间复杂度 $O(n)$。
105115
106116<!-- tabs:start -->
107117
108118#### Python3
109119
110120``` python
111-
121+ class UnionFind :
122+ def __init__ (self ):
123+ self .p = {}
124+ self .size = {}
125+
126+ def find (self , x ):
127+ if x not in self .p:
128+ self .p[x] = x
129+ self .size[x] = 1
130+ if self .p[x] != x:
131+ self .p[x] = self .find(self .p[x])
132+ return self .p[x]
133+
134+ def union (self , a , b ):
135+ pa, pb = self .find(a), self .find(b)
136+ if pa == pb:
137+ return False
138+ if self .size[pa] > self .size[pb]:
139+ self .p[pb] = pa
140+ self .size[pa] += self .size[pb]
141+ else :
142+ self .p[pa] = pb
143+ self .size[pb] += self .size[pa]
144+ return True
145+
146+
147+ class Solution :
148+ def maxActivated (self , points : List[List[int ]]) -> int :
149+ uf = UnionFind()
150+ m = int (3e9 )
151+
152+ for x, y in points:
153+ uf.union(x, y + m)
154+
155+ cnt = Counter()
156+ for x, _ in points:
157+ cnt[uf.find(x)] += 1
158+
159+ mx1 = mx2 = 0
160+ for x in cnt.values():
161+ if mx1 < x:
162+ mx2 = mx1
163+ mx1 = x
164+ elif mx2 < x:
165+ mx2 = x
166+ return mx1 + mx2 + 1
112167```
113168
114169#### Java
115170
116171``` java
117-
172+ class UnionFind {
173+ Map<Long , Long > p = new HashMap<> ();
174+ Map<Long , Integer > size = new HashMap<> ();
175+
176+ long find (long x ) {
177+ if (! p. containsKey(x)) {
178+ p. put(x, x);
179+ size. put(x, 1 );
180+ }
181+ if (p. get(x) != x) {
182+ p. put(x, find(p. get(x)));
183+ }
184+ return p. get(x);
185+ }
186+
187+ boolean union (long a , long b ) {
188+ long pa = find(a), pb = find(b);
189+ if (pa == pb) {
190+ return false ;
191+ }
192+
193+ int sa = size. get(pa), sb = size. get(pb);
194+ if (sa > sb) {
195+ p. put(pb, pa);
196+ size. put(pa, sa + sb);
197+ } else {
198+ p. put(pa, pb);
199+ size. put(pb, sa + sb);
200+ }
201+ return true ;
202+ }
203+ }
204+
205+ class Solution {
206+ public int maxActivated (int [][] points ) {
207+ UnionFind uf = new UnionFind ();
208+ long m = (long ) 3e9 ;
209+
210+ for (int [] p : points) {
211+ uf. union(p[0 ], p[1 ] + m);
212+ }
213+
214+ Map<Long , Integer > cnt = new HashMap<> ();
215+ for (int [] p : points) {
216+ cnt. merge(uf. find(p[0 ]), 1 , Integer :: sum);
217+ }
218+
219+ int mx1 = 0 , mx2 = 0 ;
220+ for (int x : cnt. values()) {
221+ if (mx1 < x) {
222+ mx2 = mx1;
223+ mx1 = x;
224+ } else if (mx2 < x) {
225+ mx2 = x;
226+ }
227+ }
228+
229+ return mx1 + mx2 + 1 ;
230+ }
231+ }
118232```
119233
120234#### C++
121235
122236``` cpp
123-
237+ class UnionFind {
238+ public:
239+ unordered_map<long long, long long> p;
240+ unordered_map<long long, int> sz;
241+
242+ long long find(long long x) {
243+ if (!p.count(x)) {
244+ p[x] = x;
245+ sz[x] = 1;
246+ }
247+ if (p[x] != x) {
248+ p[x] = find(p[x]);
249+ }
250+ return p[x];
251+ }
252+
253+ bool unite(long long a, long long b) {
254+ long long pa = find(a), pb = find(b);
255+ if (pa == pb) return false;
256+
257+ if (sz[pa] > sz[pb]) {
258+ p[pb] = pa;
259+ sz[pa] += sz[pb];
260+ } else {
261+ p[pa] = pb;
262+ sz[pb] += sz[pa];
263+ }
264+ return true;
265+ }
266+ };
267+
268+ class Solution {
269+ public:
270+ int maxActivated(vector<vector<int >>& points) {
271+ UnionFind uf;
272+ long long m = (long long) 3e9;
273+
274+ for (auto& p : points) {
275+ uf.unite(p[0], p[1] + m);
276+ }
277+
278+ unordered_map<long long , int > cnt;
279+ for (auto & p : points) {
280+ long long root = uf.find(p[0]);
281+ cnt[root]++;
282+ }
283+
284+ int mx1 = 0, mx2 = 0;
285+ for (auto& [_, x] : cnt) {
286+ if (mx1 < x) {
287+ mx2 = mx1;
288+ mx1 = x;
289+ } else if (mx2 < x) {
290+ mx2 = x;
291+ }
292+ }
293+
294+ return mx1 + mx2 + 1;
295+ }
296+ };
124297```
125298
126299#### Go
127300
128301``` go
302+ type UnionFind struct {
303+ p map [int64 ]int64
304+ size map [int64 ]int
305+ }
306+
307+ func NewUnionFind () *UnionFind {
308+ return &UnionFind{
309+ p: map [int64 ]int64 {},
310+ size: map [int64 ]int {},
311+ }
312+ }
313+
314+ func (uf *UnionFind ) find (x int64 ) int64 {
315+ if _ , ok := uf.p [x]; !ok {
316+ uf.p [x] = x
317+ uf.size [x] = 1
318+ }
319+ if uf.p [x] != x {
320+ uf.p [x] = uf.find (uf.p [x])
321+ }
322+ return uf.p [x]
323+ }
324+
325+ func (uf *UnionFind ) union (a , b int64 ) bool {
326+ pa , pb := uf.find (a), uf.find (b)
327+ if pa == pb {
328+ return false
329+ }
330+ if uf.size [pa] > uf.size [pb] {
331+ uf.p [pb] = pa
332+ uf.size [pa] += uf.size [pb]
333+ } else {
334+ uf.p [pa] = pb
335+ uf.size [pb] += uf.size [pa]
336+ }
337+ return true
338+ }
339+
340+ func maxActivated (points [][]int ) int {
341+ uf := NewUnionFind ()
342+ m := int64 (3e9 )
343+
344+ for _ , p := range points {
345+ uf.union (int64 (p[0 ]), int64 (p[1 ])+m)
346+ }
347+
348+ cnt := map [int64 ]int {}
349+ for _ , p := range points {
350+ root := uf.find (int64 (p[0 ]))
351+ cnt[root]++
352+ }
353+
354+ mx1 , mx2 := 0 , 0
355+ for _ , x := range cnt {
356+ if mx1 < x {
357+ mx2 = mx1
358+ mx1 = x
359+ } else if mx2 < x {
360+ mx2 = x
361+ }
362+ }
363+
364+ return mx1 + mx2 + 1
365+ }
366+ ```
129367
368+ #### TypeScript
369+
370+ ``` ts
371+ class UnionFind {
372+ p: Map <number , number > = new Map ();
373+ size: Map <number , number > = new Map ();
374+
375+ find(x : number ): number {
376+ if (! this .p .has (x )) {
377+ this .p .set (x , x );
378+ this .size .set (x , 1 );
379+ }
380+ if (this .p .get (x )! !== x ) {
381+ this .p .set (x , this .find (this .p .get (x )! ));
382+ }
383+ return this .p .get (x )! ;
384+ }
385+
386+ union(a : number , b : number ): boolean {
387+ const pa = this .find (a );
388+ const pb = this .find (b );
389+ if (pa === pb ) return false ;
390+
391+ const sa = this .size .get (pa )! ;
392+ const sb = this .size .get (pb )! ;
393+
394+ if (sa > sb ) {
395+ this .p .set (pb , pa );
396+ this .size .set (pa , sa + sb );
397+ } else {
398+ this .p .set (pa , pb );
399+ this .size .set (pb , sa + sb );
400+ }
401+ return true ;
402+ }
403+ }
404+
405+ function maxActivated(points : number [][]): number {
406+ const uf = new UnionFind ();
407+ const m = 3e9 ;
408+
409+ for (const [x, y] of points ) {
410+ uf .union (x , y + m );
411+ }
412+
413+ const cnt = new Map <number , number >();
414+ for (const [x] of points ) {
415+ const root = uf .find (x );
416+ cnt .set (root , (cnt .get (root ) ?? 0 ) + 1 );
417+ }
418+
419+ let mx1 = 0 ,
420+ mx2 = 0 ;
421+ for (const x of cnt .values ()) {
422+ if (mx1 < x ) {
423+ mx2 = mx1 ;
424+ mx1 = x ;
425+ } else if (mx2 < x ) {
426+ mx2 = x ;
427+ }
428+ }
429+
430+ return mx1 + mx2 + 1 ;
431+ }
130432```
131433
132434<!-- tabs:end -->
0 commit comments