在二维平面上,我们将石头放置在一些整数坐标点上。每个坐标点上最多只能有一块石头。
现在,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
Review:
脑海里闪过Union-Find算法,遍历一遍数组,每增加一个点判断其联通性,最后输出点的个数-组数就是可执行的move操作数
当然可以做一些优化
每次对代码做优化也是一件比较锻炼能力的步骤
Code:
class Solution {
int[] parent = null;
int size = 0;
//判断联通
final Integer[] record = new Integer[20000];
public int removeStones(final int[][] stones) {
//初始化数组
parent = new int[stones.length];
for (int i = 0; i < stones.length; i++) {
parent[i] = i;
int[] stone = stones[i];
Integer xInt = record[stone[0]];
Integer yInt = record[stone[1] + 10000];
if (xInt == null && yInt == null) {
record[stone[0]] = i;
record[stone[1] + 10000] = i;
size++;
} else if (xInt == null) {
record[stone[0]] = i;
union(yInt, i, false);
} else if (yInt == null) {
record[stone[1] + 10000] = i;
union(xInt, i, false);
} else {
union(xInt, yInt, true);
}
}
return stones.length - size;
}
private void union(int a, int b, boolean flag) {
int ap = parent[a];
int bp = parent[b];
if (ap == bp) return;
else if (ap != a || bp != b) union(ap, bp, flag);
else {
parent[b] = a;
if (flag) {
size--;
}
}
}
}