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
Note:
1 <= stones.length <= 1000
0 <= stones[i][j] < 10000
题目链接:https://leetcode.com/problems/most-stones-removed-with-same-row-or-column/
题目分析:题意是一个点必须所在行或列还有别的点才能删,问最多能删多少次,很明显就是把在同一行或列的点都放到一个set里,然后每个set最后只会留一个元素,所以答案就是n-set的大小,并查集维护
3ms,时间击败98.87%
class Solution {
class UnionFind {
int n;
int[] fa;
UnionFind(int n) {
this.n = n;
this.fa = new int[n];
for (int i = 0; i < n; i++) {
this.fa[i] = i;
}
}
int find(int x) {
if (x == this.fa[x]) {
return x;
}
this.fa[x] = find(this.fa[x]);
return this.fa[x];
}
void union(int a, int b) {
int r1 = find(a);
int r2 = find(b);
if (r1 != r2) {
this.fa[r1] = r2;
}
}
int getComponents() {
int ans = 0;
for (int i = 0; i < n; i++) {
if (find(i) == i) {
ans++;
}
}
return ans;
}
}
public int removeStones(int[][] stones) {
UnionFind solver = new UnionFind(stones.length);
// for (int i = 0; i < stones.length; i++) {
// for (int j = i + 1; j < stones.length; j++) {
// if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) {
// solver.union(i, j);
// }
// }
// }
int[] preRow = new int[10000];
int[] preCol = new int[10000];
for (int i = 0; i < stones.length; i++) {
if (preRow[stones[i][0]] == 0) {
preRow[stones[i][0]] = i + 1;
} else {
solver.union(preRow[stones[i][0]] - 1, i);
}
if (preCol[stones[i][1]] == 0) {
preCol[stones[i][1]] = i + 1;
} else {
solver.union(preCol[stones[i][1]] - 1, i);
}
}
return stones.length - solver.getComponents();
}
}