并查集解法一
class Solution {
Map<String,Integer> placeToIndex = new HashMap<String,Integer>();
Map<String,List<Integer>> rcPlace = new HashMap<String,List<Integer>>();
public int removeStones(int[][] stones) {
int n = stones.length;
int index = 0;
UnionFind uf = new UnionFind(n);
for(int i =0;i < n;i++){
int[] stone = stones[i];
String str = stone[0] +"," + stone[1];
int si = index;
placeToIndex.put(str,index++);
String rs = "row" + stone[0];
String cs = "col" + stone[1];
if(rcPlace.get(rs) == null){
rcPlace.put(rs,new ArrayList<Integer>());
}
else
{
List<Integer> list = rcPlace.get(rs);
int s = list.get(list.size()-1);
uf.union(s,si);
}
if(rcPlace.get(cs) == null){
rcPlace.put(cs,new ArrayList<Integer>());
}
else
{
List<Integer> list = rcPlace.get(cs);
int s = list.get(list.size()-1);
uf.union(s,si);
}
rcPlace.get(rs).add(si);
rcPlace.get(cs).add(si);
}
return n - uf.count;
}
public class UnionFind{
int[] parent;
int count;
public UnionFind(int n){
parent = new int[n];
count = n;
for(int i=0;i<n;i++)
parent[i] = i;
}
public int find(int x){
//路径压缩的方式
if(parent[x] != x){
parent[x] = find(parent[x]);
}
return parent[x];
}
public void union(int x,int y){//合并
int rootX = find(x);
int rootY = find(y);
if(rootX == rootY)
return ;
parent[rootX] = rootY;
count -= 1;
}
}
}
并查集解法二
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int removeStones(int[][] stones) {
UnionFind unionFind = new UnionFind();
for (int[] stone : stones) {
// 下面这三种写法任选其一
// unionFind.union(~stone[0], stone[1]);
// unionFind.union(stone[0] - 10001, stone[1]);
unionFind.union(stone[0] + 10001, stone[1]);
}
return stones.length - unionFind.getCount();
}
private class UnionFind {
private Map<Integer, Integer> parent;
private int count;
public UnionFind() {
this.parent = new HashMap<>();
this.count = 0;
}
public int getCount() {
return count;
}
public int find(int x) {
if (!parent.containsKey(x)) {
parent.put(x, x);
// 并查集集中新加入一个结点,结点的父亲结点是它自己,所以连通分量的总数 +1
count++;
}
if (x != parent.get(x)) {
parent.put(x, find(parent.get(x)));
}
return parent.get(x);
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}
parent.put(rootX, rootY);
// 两个连通分量合并成为一个,连通分量的总数 -1
count--;
}
}
}