這是乙個經典的換座位問題,可以很好地利用並查集解決。如果有n對情侶彼此糾纏,那麼共需要交換n-1次。知道這個定律後,咱們只需用並查集統計出有幾個團即可。注:並查集的按秩合併和路徑壓縮是很好地技巧,咱們再在並查集內部加乙個父親節點統計兒子數量的字典即可。
from collections import defaultdict
class
solution
:def
minswapscouples
(self, row: list[
int])-
>
int:
class
unionfind
:def
__init__
(self, n)
: self.father =[-
1for _ in
range
(n)]
self.rank =[0
for _ in
range
(n)]
self.father2childnum = defaultdict(
int)
defunion
(self, a, b)
: r1, r2 = self.find(a)
, self.find(b)
if r1 == r2:
return
if self.rank[r1]
<= self.rank[r2]
: self.rank[r1]
=max
(self.rank[r2]+1
, self.rank[r1]
) self.father[r1]
= r2
self.father2childnum[r2]
+= self.father2childnum[r1]+1
del self.father2childnum[r1]
else
: self.rank[r2]
=max
(self.rank[r1]+1
, self.rank[r2]
) self.father[r2]
= r1
self.father2childnum[r1]
+= self.father2childnum[r2]+1
del self.father2childnum[r2]
deffind
(self, a)
: l =
while self.father[a]
>=0:
a = self.father[a]
for num in l:
self.father[num]
= a return a
u = unionfind(
len(row)
)for i in
range
(len
(row)):
if row[i]&1
: row[i]-=1
for i in
range(0
,len
(row),2
):u.union(row[i]
, row[i+1]
) ret =
0for father in u.father2childnum:
ret += u.father2childnum[father]
return ret
leetcode 765 情侶牽手(陣列)
n 對情侶坐在連續排列的 2n 個座位上,想要牽到對方的手。計算最少交換座位的次數,以便每對情侶可以並肩坐在一起。一次交換可選擇任意兩人,讓他們站起來交換座位。人和座位用 0 到 2n 1 的整數表示,情侶們按順序編號,第一對是 0,1 第二對是 2,3 以此類推,最後一對是 2n 2,2n 1 這...
LeetCode 765 情侶牽手 困難
題目 765.情侶牽手 n 對情侶坐在連續排列的 2n 個座位上,想要牽到對方的手。計算最少交換座位的次數,以便每對情侶可以並肩坐在一起。一次交換可選擇任意兩人,讓他們站起來交換座位。人和座位用 0 到 2n 1 的整數表示,情侶們按順序編號,第一對是 0,1 第二對是 2,3 以此類推,最後一對是...
並查集 並查集
本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...