题目描述:
在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。
现在,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
思路分析:
题目理解起来实际就是求独立分量的个数。这类题就用并查集,一开始被两个坐标的比较限制,实际只要二者满足一个即可。利用一个数组来存每个位置的组号,满足同行同列就进行归并。初始所有的组号都为-1,最后统计剩余的-1个数,总数减去独立分量的个数即为所求。
代码:
1 class Solution { 2 public: 3 int find(vector<int>&f, int x) 4 { 5 return f[x]==-1?x:find(f, f[x]); 6 } 7 void u(vector<int>&f, int i, int j) 8 { 9 int fx = find(f, i); 10 int fy = find(f, j); 11 if(fx!=fy) 12 f[fx] = fy; 13 } 14 int removeStones(vector<vector<int>>& stones) { 15 if(stones.size()==0) 16 return 0; 17 int n = stones.size(); 18 vector<int> f(n, -1); 19 for(int i=0; i<n; i++) 20 { 21 for(int j=i+1; j<n; j++) 22 { 23 if(stones[i][0]==stones[j][0]||stones[i][1]==stones[j][1]) 24 { 25 u(f, i, j); 26 } 27 } 28 } 29 int cnt=0; 30 for(int i=0; i<n; i++) 31 { 32 if(f[i]==-1) 33 cnt++; 34 } 35 return n-cnt; 36 } 37 };