class UnionFind{
private:
int root_num;
vector<int> father;
vector<int> subnode;
public:
UnionFind(int n){
root_num=0;
father.resize(n);
subnode.resize(n);
for(int i=0;i<n;i++){
father[i]=i;
subnode[i]=1;
}
}
int find(int x){
while(father[x]!=x){
father[x]=father[father[x]];
x=father[x];
}
return x;
}
bool ifConnect(int x,int y){
return find(x)==find(y);
}
void connect(int x,int y){
int root_x=find(x);
int root_y=find(y);
if(root_x==root_y) return;
if(subnode[root_y]<subnode[root_x]){
father[root_y]=root_x;
subnode[root_x]+=subnode[root_y];
}else{
father[root_x]=root_y;
subnode[root_y]+=subnode[root_x];
}
root_num--;
}
int get_root_num(){
return root_num;
}
void remove(){
root_num--;
}
void add(){
root_num++;
}
};
class Solution {
public:
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
int size=positions.size();
vector<int> res(size,1);
vector<vector<int>> map(m,vector<int>(n,-1));
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
UnionFind uf(size);
for(int i=0;i<size;i++){
if(map[positions[i][0]][positions[i][1]]!=-1){//存在重复点
res[i]=uf.get_root_num();
continue;
}
uf.add();//因为可能存在重复点,root_num初始化为n计算麻烦,遍历一个点root_num加1更简洁
for(const auto& d:dir){
int newX=positions[i][0]+d[0],newY=positions[i][1]+d[1];
if(newX<0 || newX>m-1 || newY<0 || newY>n-1) continue;
if(map[newX][newY]!=-1)
uf.connect(i,map[newX][newY]);
}
map[positions[i][0]][positions[i][1]]=i;
res[i]=uf.get_root_num();
}
return res;
}
};