-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathP_711.java
More file actions
67 lines (61 loc) · 2.46 KB
/
Copy pathP_711.java
File metadata and controls
67 lines (61 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package leetcode.hard;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class P_711 {
private static final int[][] DIRS = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
private static final int[][] DIHEDRAL_DIRS = { { -1, -1 }, { -1, 1 }, { 1, -1 }, { 1, 1 } };
// https://en.wikipedia.org/wiki/Dihedral_group
public int numDistinctIslands2(int[][] grid) {
final Set<String> islands = new HashSet<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
final List<int[]> cells = new ArrayList<>();
dfs(i, j, grid, cells);
islands.add(norm(cells));
}
}
}
return islands.size();
}
private static String norm(List<int[]> cells) {
final TreeSet<String> normShapes = new TreeSet<>();
for (int[] dir : DIHEDRAL_DIRS) {
final List<int[]> s1 = new ArrayList<>();
final List<int[]> s2 = new ArrayList<>();
for (int[] cell : cells) {
final int x = cell[0];
final int y = cell[1];
s1.add(new int[] { dir[0] * x, dir[1] * y });
s2.add(new int[] { dir[0] * y, dir[1] * x });
}
for (List<int[]> s : Arrays.asList(s1, s2)) {
// Sort is not important, just used to always pick the same value when hashing the path
s.sort((o1, o2) -> o1[0] != o2[0] ? Integer.compare(o1[0], o2[0])
: Integer.compare(o1[1], o2[1]));
final int x = s.get(0)[0];
final int y = s.get(0)[1];
final StringBuilder b = new StringBuilder();
for (int[] p : s) {
b.append(p[0] - x).append(':').append(p[1] - y).append(':');
}
normShapes.add(b.toString());
}
}
return normShapes.first();
}
private static void dfs(int i, int j, int[][] grid, List<int[]> cells) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != 1) {
return;
}
cells.add(new int[] { i, j });
grid[i][j] = -1;
for (int[] dir : DIRS) {
dfs(i + dir[0], j + dir[1], grid, cells);
}
}
}