跳
本来懒得记录= =但是找工作前的代码真是丢人。。。
这应该是UF最好的应用之一了。
- 二维转一维建UF
- 需要注意 x * col + y
- 算完结果的i再传到union或者find里比find(x, y)这样进去再算好多了。。我是不是傻逼啊
- UNION的标准是题的关键,
- 上下左右相邻。不用UF做的话牵扯一个问题,比如上面下面是一个岛,有可能会算2次,UF没这个问题了= =
- UNION了相应岛的数量-1,所以UF里可以自定义一些东西来实时更新,比如当前岛的数量,上一题是最大岛的面积
最难的是二维转一维,好久没做了。然后一开始犹豫了初始化,是不是要全部PARENT[]都设0,答案是没必要……
然后树随意压缩下。。懒得全指ROOT了。。重点不是这个
时间复杂度要求k*log(mn) k是add岛屿的数量 logMN就是UF里树的高度= =感觉这是赤裸裸的提示,知道时间复杂度基本就知道UF了。。
这里其实有BUG的integer的比较用==如果-127~128范围之外会错误,还是得.equals. 然后UNION的时候忘更新WEIGHT了。。。。
class Solution {
public class WeightedUF {
int num;
Map<Integer, Integer> parents;
Map<Integer, Integer> size;
public WeightedUF() {
num = 0;
parents = new HashMap<>();
size = new HashMap<>();
}
public Integer find(Integer n) {
if (n == null || !parents.containsKey(n)) return null;
Integer root = n;
while (root != parents.get(root)) {
parents.put(root, parents.get(parents.get(root)));
root = parents.get(root);
}
return root;
}
public void union(Integer a, Integer b) {
Integer rootA = find(a);
Integer rootB = find(b);
if (rootA == null || rootB == null || rootA == rootB) return;
Integer sizeA = size.get(a);
Integer sizeB = size.get(b);
parents.put(sizeA > sizeB ? rootB : rootA, sizeA > sizeB ? rootA : rootB);
num --;
return;
}
public void add(Integer n) {
if (!parents.containsKey(n)) {
parents.put(n, n);
size.put(n, 1);
num ++;
}
}
}
public List<Integer> numIslands2(int m, int n, int[][] positions) {
List<Integer> result = new ArrayList<>();
if (positions.length == 0 || positions[0].length == 0) return result;
WeightedUF uf = new WeightedUF();
for (int[] pair : positions) {
int x = pair[0];
int y = pair[1];
Integer i = x * n + y;
uf.add(i);
// right
if (x + 1 < m) uf.union(i, (x + 1) * n + y);
// left
if (x - 1 >= 0) uf.union(i, (x - 1) * n + y);
// up
if (y + 1 < n) uf.union(i, (x * n + y + 1));
// down
if (y - 1 >= 0) uf.union(i, (x * n + y - 1));
result.add(uf.num);
}
return result;
}
}