modify code on class

pull/6/head
左程云 4 years ago
parent c3dbd234e7
commit 0b3c58a8ef

@ -7,10 +7,11 @@ public class Code01_FriendCircles {
public static int findCircleNum(int[][] M) { public static int findCircleNum(int[][] M) {
int N = M.length; int N = M.length;
// {0} {1} {2} {N-1}
UnionFind unionFind = new UnionFind(N); UnionFind unionFind = new UnionFind(N);
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) { for (int j = i + 1; j < N; j++) {
if (M[i][j] == 1) { if (M[i][j] == 1) { // i和j互相认识
unionFind.union(i, j); unionFind.union(i, j);
} }
} }
@ -19,9 +20,14 @@ public class Code01_FriendCircles {
} }
public static class UnionFind { public static class UnionFind {
// parent[i] = k i的父亲是k
private int[] parent; private int[] parent;
// size[i] = k 如果i是代表节点size[i]才有意义,否则无意义
// i所在的集合大小是多少
private int[] size; private int[] size;
// 辅助结构
private int[] help; private int[] help;
// 一共有多少个集合
private int sets; private int sets;
public UnionFind(int N) { public UnionFind(int N) {
@ -35,6 +41,8 @@ public class Code01_FriendCircles {
} }
} }
// 从i开始一直往上往上到不能再往上代表节点返回
// 这个过程要做路径压缩
private int find(int i) { private int find(int i) {
int hi = 0; int hi = 0;
while (i != parent[i]) { while (i != parent[i]) {

@ -23,6 +23,7 @@ public class Code02_NumberOfIslands {
return islands; return islands;
} }
// 从(i,j)这个位置出发,把所有练成一片的'1'字符变成0
public static void infect(char[][] board, int i, int j) { public static void infect(char[][] board, int i, int j) {
if (i < 0 || i == board.length || j < 0 || j == board[0].length || board[i][j] != '1') { if (i < 0 || i == board.length || j < 0 || j == board[0].length || board[i][j] != '1') {
return; return;
@ -49,6 +50,7 @@ public class Code02_NumberOfIslands {
} }
UnionFind1<Dot> uf = new UnionFind1<>(dotList); UnionFind1<Dot> uf = new UnionFind1<>(dotList);
for (int j = 1; j < col; j++) { for (int j = 1; j < col; j++) {
// (0,j) (0,0)跳过了 (0,1) (0,2) (0,3)
if (board[0][j - 1] == '1' && board[0][j] == '1') { if (board[0][j - 1] == '1' && board[0][j] == '1') {
uf.union(dots[0][j - 1], dots[0][j]); uf.union(dots[0][j - 1], dots[0][j]);
} }
@ -192,10 +194,12 @@ public class Code02_NumberOfIslands {
} }
} }
// (r,c) -> i
private int index(int r, int c) { private int index(int r, int c) {
return r * col + c; return r * col + c;
} }
// 原始位置 -> 下标
private int find(int i) { private int find(int i) {
int hi = 0; int hi = 0;
while (i != parent[i]) { while (i != parent[i]) {

@ -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;
} }

Loading…
Cancel
Save