【Leetcode】711. Number of Distinct Islands II
技術標籤:LC DFS、BFS與圖論雜湊表hash雜湊演算法
題目地址:
https://leetcode.com/problems/number-of-distinct-islands-ii/
給定一個 m m m行 n n n列的 0 − 1 0-1 0−1矩陣,每個 1 1 1連通塊視為一個島嶼。這裡的連通是四連通。兩個島嶼相同當且僅當其中一個可以通過旋轉 0 ° , 9 0 ° , 18 0 ° , 27 0 ° 0^\degree,90^\degree,180^\degree,270^\degree 0°,90°,180°,270°或者鏡面翻轉後,與另一個島嶼重合。問一共有多少個不同的島嶼。
可以用雜湊。這裡需要保證兩個相同形狀的島嶼雜湊值一樣。我們可以採用這樣的雜湊方式,設某個島嶼的所有
1
1
1的座標是
(
a
[
i
]
x
,
a
[
i
]
y
)
(a[i]_x,a[i]_y)
(a[i]x,a[i]y),其中
0
≤
i
<
k
0\le i<k
0≤i<k,那麼令其雜湊值為:
∑
i
<
j
(
a
[
i
]
x
−
a
[
j
]
x
)
2
+
(
a
[
i
]
y
−
a
[
j
]
y
)
2
\sum_{i<j}\sqrt{(a[i]_x-a[j]_x)^2+(a[i]_y-a[j]_y)^2}
i<j∑(a[i
import java.util.ArrayList;
import java.util.List;
public class Solution {
public int numDistinctIslands2(int[][] grid) {
double eps = 1E-10;
List<int[]> list = new ArrayList<>();
List<Double> hashList = new ArrayList<>();
int[] d = {1, 0, -1, 0, 1};
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
// 將當前1連通塊裡所有的1的座標存入list中
dfs(i, j, grid, list, d);
// 得到島嶼的雜湊值
double hash = hash(list);
// 在hashList裡找有沒有一樣的島嶼
boolean found = false;
for (Double v : hashList) {
if (Math.abs(v - hash) < eps) {
found = true;
break;
}
}
// 如果沒有,則說明發現了新島嶼,加入hashList
if (!found) {
hashList.add(hash);
}
list.clear();
}
}
}
return hashList.size();
}
private double hash(List<int[]> list) {
double hash = 0;
for (int i = 0; i < list.size() - 1; i++) {
for (int j = i + 1; j < list.size(); j++) {
int[] p1 = list.get(i), p2 = list.get(j);
hash += Math.sqrt(pow2(p1[0] - p2[0]) + pow2(p1[1] - p2[1]));
}
}
return Math.sqrt(hash);
}
private double pow2(int x) {
return x * x;
}
private void dfs(int x, int y, int[][] grid, List<int[]> list, int[] d) {
list.add(new int[]{x, y});
grid[x][y] = 0;
for (int i = 0; i < 4; i++) {
int nextX = x + d[i], nextY = y + d[i + 1];
if (0 <= nextX && nextX < grid.length && 0 <= nextY && nextY < grid[0].length && grid[nextX][nextY] == 1) {
dfs(nextX, nextY, grid, list, d);
}
}
}
}
時間 O ( m n + ∑ s 2 ) O(mn + \sum s^2) O(mn+∑s2), s s s為每個島嶼的size,空間 O ( m n ) O(mn) O(mn)。