问题描述:找出孤岛的个数,孤岛定义为多个连接的1,被4个0包围,上下左右,如图。
思路,一般有矩阵的题目,要么动态规划,要么深度优先搜索和广度优先搜索算法加上相应的条件变式,这个题目也是如此,不过用并差集的话会更加的容易理解,跟128. Longest Consecutive Sequence 一样,平时已经写了一个通用的Node以及并差集的find和union算法了,最终只需要根据结果来查找出祖先节点就可以了。
代码如下:
class Node:
#最大元素集合只要找最大一个就可以了。
def __init__(self,val):
self.prev = self
self.val = val
self.rank = 0
self.size = 1
class UnionF:
max_size = 1
def find(self,x):
if x.prev == x:
return x
else:
root = self.find(x.prev)
x.prev = root
return root
def union(self,x,y):
x_fa = self.find(x)
y_fa = self.find(y)
if x_fa != y_fa:
x_size = x_fa.size #根据元素个数合并
y_size = y_fa.size
if (x_size < y_size):
x_fa.prev = y_fa
y_fa.size = y_fa.size + x_fa.size
self.max_size = max(self.max_size,y_fa.size)
else:
y_fa.prev = x_fa
x_fa.size = x_fa.size + y_fa.size
self.max_size = max(self.max_size,x_fa.size)
class Solution:
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
if not grid:
return 0
m = len(grid)
n = len(grid[0])
visited = []
hm = {}
ans = 0
uf = UnionF()
nodeSet = {(x,y):Node((x,y)) for x in range(m) for y in range(n) if grid[x][y]=="1"}
for p in nodeSet:
cur_x,cur_y = p[0],p[1]
for point in [(cur_x+1,cur_y),(cur_x-1,cur_y),(cur_x,cur_y-1),(cur_x,cur_y+1)]:
x,y = point[0],point[1]
if (x,y) in nodeSet:
uf.union(nodeSet[(cur_x,cur_y)],nodeSet[(x,y)])
for k in nodeSet:
if nodeSet[k].prev.val == k:
ans += 1
return ans