leetcode 947. 移除最多的同行或同列石头
问题描述: n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。
如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。
给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。
示例 1:
输入: 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] 不能移除,因为它没有与另一块石头同行/列。
示例 2:
输入: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
输出: 3
解释: 一种移除 3 块石头的方法如下所示:
1. 移除石头 [2,2] ,因为它和 [2,0] 同行。
2. 移除石头 [2,0] ,因为它和 [0,0] 同列。
3. 移除石头 [0,2] ,因为它和 [0,0] 同行。
石头 [0,0] 和 [1,1] 不能移除,因为它们没有与另一块石头同行/列。
思路: 并查集 用map维护石子的x与y坐标,同行或同列的放到一个集合,最后返回的就是总石子数减去集合数。
/**
* @param {number[][]} stones
* @return {number}
*/
var removeStones = function(stones) {
let unionStone=new UnionSet(stones.length);
let map1=new Map();
let map2=new Map();
for(let i=0;i<stones.length;i++){
if(map1.has(stones[i][0])){
unionStone.merge(i,map1.get(stones[i][0]))
}
if(map2.has(stones[i][1])){
unionStone.merge(i,map2.get(stones[i][1]))
}
map1.set(stones[i][0],i);
map2.set(stones[i][1],i)
}
let res=0;
for(let i=0;i<unionStone.node.length;i++){
if(i==unionStone.node[i])res++
}
return stones.length-res
};
class UnionSet{
constructor(n){
this.node=new Array(n).fill(0).map((item,index)=>index);
}
find(x){
return this.node[x]=(this.node[x]==x?x:this.find(this.node[x]))
}
merge(x,y){
let fa=this.find(x),fb=this.find(y);
this.node[fa]=fb;
}
}