题目描述
n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。
如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。
给你一个长度为 n 的数组 stones ,其中 stones [ i ] = [ xi , yi ] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。
力扣:947. 移除最多的同行或同列石头
输入:stones = [ [ 0 , 0 ] , [ 0 , 1 ] , [ 1 ,0 ] , [ 1 , 2 ] , [ 2 , 1 ] , [ 2 , 2 ] ]
输出:5
解释:一种移除 5 块石头的方法如下所示:
1、 移除石头 [ 2 , 2 ] ,因为它和 [ 2 , 1 ] 同行。
2、移除石头 [ 2 , 1 ] ,因为它和 [ 0 , 1 ] 同列。
3、移除石头 [ 1 , 2 ] ,因为它和 [ 1 , 0 ] 同行。
4、移除石头 [ 1 , 0 ] ,因为它和 [ 0 , 0 ] 同列。
5、移除石头 [ 0 , 1 ] ,因为它和 [ 0 , 0 ] 同行。
石头 [ 0 , 0 ] 不能移除,因为它没有与另一块石头同行/列。
题目分析
并查集模板题应用
class Solution {
int maxn = 20005; //根据坐标范围而定
int[] father = new int[maxn];
// 并查集初始化
public void init(){
Arrays.fill(father , -1);
}
// 并查集里寻根的过程
public int find(int u){
return father[u] == -1 ? u : find(father[u]);
}
// 将 v -> u 这条边加入并查集
public void union(int u , int v){
int rootu = find(u);
int rootv = find(v);
if(rootu != rootv){
father[rootv] = rootu;
}
}
// 判断 u 和 v 是否找到同一个根
public boolean same(int u , int v){
return find(u) == find(v);
}
public int removeStones(int[][] stones) {
init();
for(int[] stone : stones){
union(stone[0] , stone[1] + 10000);
}
Map<Integer , Boolean> umap = new HashMap<>();
for(int[] stone : stones){
umap.put(find(stone[0]) , true);
umap.put(find(stone[1] + 10000) , true);
}
return stones.length - umap.size();
}
}