Number of Distinct Islands

medium dfs hash set

Problem

Two islands are 'the same' if they have the same shape (translation-only). Count distinct shapes.

Inputgrid=[[1,1,0,0,0],[1,1,0,0,0],[0,0,0,1,1],[0,0,0,1,1]]
Output1
Both islands have the same 2×2 shape.

def num_distinct_islands(grid):
    m, n = len(grid), len(grid[0]); seen = set(); shapes = set()
    def dfs(r, c, br, bc, shape):
        if (r < 0 or r >= m or c < 0 or c >= n or grid[r][c] == 0 or (r, c) in seen): return
        seen.add((r, c)); shape.append((r - br, c - bc))
        for dr, dc in ((1,0),(-1,0),(0,1),(0,-1)): dfs(r + dr, c + dc, br, bc, shape)
    for r in range(m):
        for c in range(n):
            if grid[r][c] == 1 and (r, c) not in seen:
                shape = []; dfs(r, c, r, c, shape); shapes.add(tuple(shape))
    return len(shapes)
function numDistinctIslands(grid) {
  const m = grid.length, n = grid[0].length;
  const seen = new Set(); const shapes = new Set();
  const dfs = (r, c, br, bc, shape) => {
    const k = r + ',' + c;
    if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] === 0 || seen.has(k)) return;
    seen.add(k); shape.push((r - br) + ':' + (c - bc));
    for (const [dr, dc] of [[1,0],[-1,0],[0,1],[0,-1]]) dfs(r + dr, c + dc, br, bc, shape);
  };
  for (let r = 0; r < m; r++) for (let c = 0; c < n; c++)
    if (grid[r][c] === 1 && !seen.has(r + ',' + c)) {
      const shape = []; dfs(r, c, r, c, shape); shapes.add(shape.join('|'));
    }
  return shapes.size;
}
int numDistinctIslands(int[][] grid) {
    int m = grid.length, n = grid[0].length;
    Set shapes = new HashSet<>();
    for (int r = 0; r < m; r++) for (int c = 0; c < n; c++)
        if (grid[r][c] == 1) {
            StringBuilder sb = new StringBuilder();
            dfs(grid, r, c, r, c, sb, m, n);
            shapes.add(sb.toString());
        }
    return shapes.size();
}
void dfs(int[][] g, int r, int c, int br, int bc, StringBuilder sb, int m, int n) {
    if (r < 0 || r >= m || c < 0 || c >= n || g[r][c] != 1) return;
    g[r][c] = -1; sb.append(r - br).append(':').append(c - bc).append(',');
    int[][] D = {{1,0},{-1,0},{0,1},{0,-1}};
    for (int[] d : D) dfs(g, r + d[0], c + d[1], br, bc, sb, m, n);
}
void dfs(vector>& g, int r, int c, int br, int bc, string& s) {
    int m = g.size(), n = g[0].size();
    if (r < 0 || r >= m || c < 0 || c >= n || g[r][c] != 1) return;
    g[r][c] = -1; s += to_string(r - br) + ":" + to_string(c - bc) + ",";
    int D[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    for (auto& d : D) dfs(g, r + d[0], c + d[1], br, bc, s);
}
int numDistinctIslands(vector>& grid) {
    set shapes;
    for (int r = 0; r < (int)grid.size(); r++) for (int c = 0; c < (int)grid[0].size(); c++)
        if (grid[r][c] == 1) { string s; dfs(grid, r, c, r, c, s); shapes.insert(s); }
    return shapes.size();
}
Time: O(m·n) Space: O(m·n)