947. 移除最多的同行或同列石头
在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。
现在,move 操作将会移除与网格上的某一块石头共享一列或一行的一块石头。
我们最多能执行多少次 move 操作?
示例 1:
输入:stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
输出:5
示例 2:
输入:stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
输出:3
示例 3:
输入:stones = [[0,0]]
输出:0
提示:
1 <= stones.length <= 1000
0 <= stones[i][j] < 10000
分析:
当两块石头i,j处于同一行或同一列时,我们就将节点i,j直接连接一条无向边
经过上述操作后,n个节点将形成多个(或一个)连通分量
对于每个连通分量而言,我们都从边缘(或叶子节点)处移除石头,最终只会剩余一个石头。
所以,最终剩余的石头数目就是上述联通分量的个数。
因此,我们只需使用并查集求出上述图中连通分量的个数即可。
AC代码:
class Solution {
public:
int f[1010];
int getf(int u)
{
return f[u]==u?u:f[u]=getf(f[u]);
}
void unionf(int u,int v)
{
f[u] = v;
}
int removeStones(vector<vector<int>>& stones) {
int n = stones.size();
int fu,fv;
for(int i=0;i<n;i++) f[i] = i;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1])
{
fu = getf(i);
fv = getf(j);
if(fu != fv) unionf(fu,fv);
}
}
}
int num = 0;
for(int i=0;i<n;i++)
{
if(f[i] == i) num++;
}
return n - num;
}
};