题目描述
n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。
如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。
给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。
解题思路
数据结构,算法
并查集,哈希表
思路
通过两个哈希表 xMap, yMap,记录每个坐标(x, y) 都存在哪些石子,这是我们用 O(1) 复杂度找到石子的关键
并查集中记录每个石子的联通情况,第 i 个项值表示 stones 的第 i 项的连通情况,最终我们找到的“可以移除的狮子的最大数量”就是 stones.length - 并查集集数量
过程
遍历所有的 stones[i]
根据 stones[i] 的 x, y,连接 xMap, yMap 中具有同坐标的石头,merge 起来
在哈希表中记录本石头的 i
遍历并查集,计算 stones.length - 并查集集数量
代码
/**
* @param {number[][]} stones
* @return {number}
*/
var removeStones = function (stones) {
const u = new UnionSet(stones.length)
const xMap = {}
const yMap = {}
stones.forEach((item, index) => {
const x = item[0]
const y = item[1]
if (xMap[x] !== undefined) {
u.merge(xMap[x], index)
}
if (yMap[y] !== undefined) {
u.merge(yMap[y], index)
}
xMap[x] = index
yMap[y] = index
})
let cnt = 0
for (let i = 0; i < stones.length; i++) {
if (u.get(i) === i) cnt++
}
return stones.length - cnt
}
class UnionSet {
constructor(n) {
this.fa = []
for (let i = 0; i < n; i++) {
this.fa[i] = i
}
}
get(x) {
return (this.fa[x] = this.fa[x] === x ? x : this.get(this.fa[x]))
}
merge(a, b) {
this.fa[this.get(a)] = this.get(b)
}
}