[LeetCode] 694. Number of Distinct Islands

Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.

Count the number of distinct islands. An island is considered to be the same as another if and only if one island can be translated (and not rotated or reflected) to equal the other.

Example 1:

11000
11000
00011
00011

Given the above grid map, return 1.

 

Example 2:

11011
10000
00001
11011

Given the above grid map, return 3.

Notice that:

11
1

and

 1
11

are considered different island shapes, because we do not consider reflection / rotation.

 

Note: The length of each dimension in the given grid does not exceed 50.

 

这个题目可以理解为是[LeetCode] 200. Number of Islands_ Medium tag: BFS的变形, 不仅仅是要判断有多少个island, 并且是要unique的, 不能翻转, 那么如果做呢, 因为我们scan的时候是一行一行得scan, 用DFS去scan的时候也有它的先后顺序, 所以可以通过每次用DFS的时候将路径记下来, 并且add进入一个ans的set里面, 最后返回len(ans), 就是distinct islands的数目了.

 

updated at 07/10, 参考题目的Solution, 思路跟之前类似, 只不过, 每个island我们将坐标都变为local的坐标, 相当于以最开始的坐标作为原点坐标, 获得相对坐标的位置, 然后将该路径记下来, 并且将其变为tuple然后add进入一个ans的set里面, 最后返回len(ans).

Updated at 08/17, 将local location的code update更加elegant.

1. Constraints

1) grid can be empty,

2) grid size <= 50 * 50

3) element will only be 0 or 1

 

2. Ideas

DFS:      T: O(m*n)      S: O(m*n)

1) edge case, not grid or len(grid[0]) == 0, return 0

2) grid[i][j] if not visited, dfs(得到它的路径), 并add进入ans 的set

3) 对于dfs, 记住路径, 并且append进入dirs

4) 返回len(ans)

 

3. Code

 1 class Solution:
 2     def numDistinctIslands(self, grid):
 3         if not gird or len(grid[0]) == 0: return 0
 4         lr, lc, ans, visited = len(grid), len(grid[0]), set(), set()
 5 
 6         def dfs(grid, i, j, visited, dirs, dirt):
 7             if 0<= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == 1 and (i, j) not in visited:
 8                 visited.add((i,j))
 9                 dirs.append(dirt)
10                 dfs(grid, i-1, j, visited, dirs, 'u')
11                 dfs(grid, i+1, j, visited, dirs, 'd')
12                 dfs(grid, i, j-1, visited, dirs, 'l')
13                 dfs(grid, i, j+1, visited, dirs, 'r')
14                 dirs.append('b') # if no this line, [[110],[011],[000],[111],[010]] can not pass
15         for i in range(lr):
16             for j in range(lc):
17                 if grid[i][j] == 1 and (i,j) not in visited:
18                     dirs = []
19                     dfs(grid, i, j,visited, dirs, 'o' )
20                     ans.add("".join(dirs))
21         return len(ans)

 

3.1  Code(利用loca 相对坐标位置)

class Solution:
    def numberDistinctIslands(self, grid):
        if not grid or len(grid[0]) == 0: return 0
        lrc, ans, visited = [len(grid), len(grid[0])], set(), set()
        def dfs(i,j,i0,j0):
            if 0 <= i < lrc[0] and 0 <= j < lrc[1] and grid[i][j] and (i,j) not in visited:
                temp.append((i-i0, j-j0))
                visited.add((i,j))
                dfs(i-1,j,i0,j0)
                dfs(i+1,j,i0,j0)
                dfs(i,j+1,i0,j0)
                dfs(i,j-1,i0,j0)

        for i in range(lrc[0]):
            for j in range(lrc[1]):
                temp = []
                dfs(i,j,i,j)
                if temp:
                    ans.add(tuple(temp))
        return len(ans)

 

4. Test cases

1) edge cases

2) [[110],[011],[000],[111],[010]]

3) 

11011
10000
00001
11011

转载于:https://www.cnblogs.com/Johnsonxiong/p/9292566.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值