图-dfs-连通分量-旋转变换-804. 不同岛屿的数量II
2020-04-04 18:25:18
问题描述:
给定一个0和1的非空的二维数组网格,一个岛是一个1(表示陆地)的组,4个方向(水平或垂直)连接。你可以假设网格的所有四条边都被水包围。
计算不同岛屿的数量。当一个岛被认为与另一个岛相同时,它们有相同的形状,或在旋转后的形状相同(90,180,或270度)或翻转(左/右方向或向上/向下方向)。
样例
Example 1:
Input: [[1,1,0,0,0],[1,0,0,0,0],[0,0,0,0,1],[0,0,0,1,1]]
Output: 1
Explanation:
The island is look like this:
11000
10000
00001
00011
Notice that:
11
1
and
1
11
are considered same island shapes. Because if we make a 180 degrees clockwise rotation on the first island, then two islands will have the same shapes.
Example 2:
Input: [[1,1,1,0,0],[1,0,0,0,1],[0,1,0,0,1],[0,1,1,1,0]]
Output: 2
Explanation:
The island is look like this:
11100
10001
01001
01110
Here are the two distinct islands:
111
1
and
1
1
Notice that:
111
1
and
1
111
are considered same island shapes. Because if we flip the first array in the up/down direction, then they have the same shapes.
注意事项
每个维度在给定网格的长度不超过50。
问题求解:
public int numDistinctIslands2(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return 0;
}
int m = grid.length, n = grid[0].length;
Set<String> res = new HashSet<>();
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1) {
List<int[]> island = new ArrayList<>();
dfs(grid, i, j, island);
res.add(getUnique(island));
}
}
}
return res.size();
}
private void dfs(int[][]grid, int x, int y, List<int[]> island) {
int m = grid.length, n = grid[0].length;
island.add(new int[]{x, y});
grid[x][y] = 0;
int[] dirs = {-1, 0, 1, 0, -1};
for (int i = 0; i < 4; ++i) {
int nx = x + dirs[i];
int ny = y + dirs[i + 1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] == 1) {
dfs(grid, nx, ny, island);
}
}
}
private String getUnique(List<int[]> island) {
List<String> sameIslands = new ArrayList<>();
int[][] trans={{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
for (int i = 0; i < 4; ++i) {
List<int[]> l1 = new ArrayList<>(), l2 = new ArrayList<>();
for (int[] is : island) {
int x = is[0], y = is[1];
l1.add(new int[]{x * trans[i][0], y * trans[i][1]});
l2.add(new int[]{y * trans[i][0], x * trans[i][1]});
}
sameIslands.add(getStr(l1));
sameIslands.add(getStr(l2));
}
Collections.sort(sameIslands);
return sameIslands.get(0);
}
private String getStr(List<int[]> island) {
Collections.sort(island, (int[] o1, int[] o2) -> o1[0] == o2[0] ? Integer.compare(o1[1], o2[1]) : Integer.compare(o1[0], o2[0]));
StringBuilder sb = new StringBuilder();
int x = island.get(0)[0], y = island.get(0)[1];
for (int[] point : island) {
sb.append((point[0] - x) + " " + (point[1] - y) + " ");
}
return sb.toString();
}

浙公网安备 33010602011771号