Most Stones Removed with Same Row or Column
On a 2D plane, we place stones at some integer coordinate points. Each coordinate point may have at most one stone.
Now, a move consists of removing a stone that shares a column or row with another stone on the grid.
What is the largest possible number of moves we can make?
Example 1:
Input: stones = [[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]]
Output: 5
Example 2:
Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
Output: 3
Example 3:
Input: stones = [[0,0]]
Output: 0
这题做的当天没有反应过来题目的意思,后来查了几个以后发现就是一道union find的类型
题目要求最后的终止条件变成,每一行,每一列都只能由一个元素,问最后台面上剩余几个棋子.
反过来想,这就是并查集的题目,用嵌套的forloop 遍历两两元素,如果发现他们有row or col是重合的,那么对他们进行merge操作,这样没进行一次操作,我们会少一个集合,那么n–.
最终会变成只剩下n个那么多的repersentative了,所以要移动的棋子个数,用原始的个数-representative的个数就可以了.这个题目我觉得叙述还是有点问题的,应该是移动的最少的个数是多少吧.
代码:
class Solution {
// make this a union find questin
public int removeStones(int[][] stones) {
if(stones == null || stones.length <=1) return 0;
int n = stones.length;
int[] parent = new int[n];
for(int i=0;i<n;i++) parent[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]) {
union(i, j, parent);
}
}
}
for(int i=0;i<parent.length;i++) {
if(i == parent[i]) {
n--;
}
}
return n;
}
private void union(int x, int y, int[] parent) {
int xp = find(x, parent);
int yp = find(y, parent);
if(xp != yp) {
parent[xp] = yp;
}
}
// each stone has a index id, which is the stones' length,
// where [0] [1] is it's row, column
private int find(int x, int[] parent) {
if(parent[x] != x) {
return parent[x] = find(parent[x], parent);
}
return x;
}
}