|
|
@ -1,6 +1,7 @@
|
|
|
|
package class09_15;
|
|
|
|
package class09_15;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
// 本题为leetcode原题
|
|
|
|
// 本题为leetcode原题
|
|
|
@ -8,8 +9,8 @@ import java.util.List;
|
|
|
|
// 所有方法都可以直接通过
|
|
|
|
// 所有方法都可以直接通过
|
|
|
|
public class Code03_NumberOfIslandsII {
|
|
|
|
public class Code03_NumberOfIslandsII {
|
|
|
|
|
|
|
|
|
|
|
|
public static List<Integer> numIslands2(int m, int n, int[][] positions) {
|
|
|
|
public static List<Integer> numIslands21(int m, int n, int[][] positions) {
|
|
|
|
UnionFind uf = new UnionFind(m, n);
|
|
|
|
UnionFind1 uf = new UnionFind1(m, n);
|
|
|
|
List<Integer> ans = new ArrayList<>();
|
|
|
|
List<Integer> ans = new ArrayList<>();
|
|
|
|
for (int[] position : positions) {
|
|
|
|
for (int[] position : positions) {
|
|
|
|
ans.add(uf.connect(position[0], position[1]));
|
|
|
|
ans.add(uf.connect(position[0], position[1]));
|
|
|
@ -17,7 +18,7 @@ public class Code03_NumberOfIslandsII {
|
|
|
|
return ans;
|
|
|
|
return ans;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static class UnionFind {
|
|
|
|
public static class UnionFind1 {
|
|
|
|
private int[] parent;
|
|
|
|
private int[] parent;
|
|
|
|
private int[] size;
|
|
|
|
private int[] size;
|
|
|
|
private int[] help;
|
|
|
|
private int[] help;
|
|
|
@ -25,7 +26,7 @@ public class Code03_NumberOfIslandsII {
|
|
|
|
private final int col;
|
|
|
|
private final int col;
|
|
|
|
private int sets;
|
|
|
|
private int sets;
|
|
|
|
|
|
|
|
|
|
|
|
public UnionFind(int m, int n) {
|
|
|
|
public UnionFind1(int m, int n) {
|
|
|
|
row = m;
|
|
|
|
row = m;
|
|
|
|
col = n;
|
|
|
|
col = n;
|
|
|
|
sets = 0;
|
|
|
|
sets = 0;
|
|
|
@ -74,16 +75,87 @@ public class Code03_NumberOfIslandsII {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int connect(int i, int j) {
|
|
|
|
public int connect(int r, int c) {
|
|
|
|
int index = index(i, j);
|
|
|
|
int index = index(r, c);
|
|
|
|
if (size[index] == 0) {
|
|
|
|
if (size[index] == 0) {
|
|
|
|
parent[index] = index;
|
|
|
|
parent[index] = index;
|
|
|
|
size[index] = 1;
|
|
|
|
size[index] = 1;
|
|
|
|
sets++;
|
|
|
|
sets++;
|
|
|
|
union(i - 1, j, i, j);
|
|
|
|
union(r - 1, c, r, c);
|
|
|
|
union(i + 1, j, i, j);
|
|
|
|
union(r + 1, c, r, c);
|
|
|
|
union(i, j - 1, i, j);
|
|
|
|
union(r, c - 1, r, c);
|
|
|
|
union(i, j + 1, i, j);
|
|
|
|
union(r, c + 1, r, c);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return sets;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 课上讲的如果m*n比较大,会经历很重的初始化,而k比较小,怎么优化的方法
|
|
|
|
|
|
|
|
public static List<Integer> numIslands22(int m, int n, int[][] positions) {
|
|
|
|
|
|
|
|
UnionFind2 uf = new UnionFind2();
|
|
|
|
|
|
|
|
List<Integer> ans = new ArrayList<>();
|
|
|
|
|
|
|
|
for (int[] position : positions) {
|
|
|
|
|
|
|
|
ans.add(uf.connect(position[0], position[1]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return ans;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static class UnionFind2 {
|
|
|
|
|
|
|
|
private HashMap<String, String> parent;
|
|
|
|
|
|
|
|
private HashMap<String, Integer> size;
|
|
|
|
|
|
|
|
private ArrayList<String> help;
|
|
|
|
|
|
|
|
private int sets;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public UnionFind2() {
|
|
|
|
|
|
|
|
parent = new HashMap<>();
|
|
|
|
|
|
|
|
size = new HashMap<>();
|
|
|
|
|
|
|
|
help = new ArrayList<>();
|
|
|
|
|
|
|
|
sets = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String find(String cur) {
|
|
|
|
|
|
|
|
while (!cur.equals(parent.get(cur))) {
|
|
|
|
|
|
|
|
help.add(cur);
|
|
|
|
|
|
|
|
cur = parent.get(cur);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (String str : help) {
|
|
|
|
|
|
|
|
parent.put(str, cur);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
help.clear();
|
|
|
|
|
|
|
|
return cur;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void union(String s1, String s2) {
|
|
|
|
|
|
|
|
if (parent.containsKey(s1) && parent.containsKey(s2)) {
|
|
|
|
|
|
|
|
String f1 = find(s1);
|
|
|
|
|
|
|
|
String f2 = find(s2);
|
|
|
|
|
|
|
|
if (!f1.equals(f2)) {
|
|
|
|
|
|
|
|
int size1 = size.get(f1);
|
|
|
|
|
|
|
|
int size2 = size.get(f2);
|
|
|
|
|
|
|
|
String big = size1 >= size2 ? f1 : f2;
|
|
|
|
|
|
|
|
String small = big == f1 ? f2 : f1;
|
|
|
|
|
|
|
|
parent.put(small, big);
|
|
|
|
|
|
|
|
size.put(big, size1 + size2);
|
|
|
|
|
|
|
|
sets--;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int connect(int r, int c) {
|
|
|
|
|
|
|
|
String key = String.valueOf(r) + "_" + String.valueOf(c);
|
|
|
|
|
|
|
|
if (!parent.containsKey(key)) {
|
|
|
|
|
|
|
|
parent.put(key, key);
|
|
|
|
|
|
|
|
size.put(key, 1);
|
|
|
|
|
|
|
|
sets++;
|
|
|
|
|
|
|
|
String up = String.valueOf(r - 1) + "_" + String.valueOf(c);
|
|
|
|
|
|
|
|
String down = String.valueOf(r + 1) + "_" + String.valueOf(c);
|
|
|
|
|
|
|
|
String left = String.valueOf(r) + "_" + String.valueOf(c - 1);
|
|
|
|
|
|
|
|
String right = String.valueOf(r) + "_" + String.valueOf(c + 1);
|
|
|
|
|
|
|
|
union(up, key);
|
|
|
|
|
|
|
|
union(down, key);
|
|
|
|
|
|
|
|
union(left, key);
|
|
|
|
|
|
|
|
union(right, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sets;
|
|
|
|
return sets;
|
|
|
|
}
|
|
|
|
}
|
|
|
|