這個題目是有 n 個島嶼,其中島嶼可能會相連,我們要知道是不是相連的方式是題目有給定一個 n x n 的矩陣,如果矩陣的位置 i, j 的值是 1 ,代表i和j 小島是有相鄰的。
這題我一開始想的方向是,其實題目已經告訴我們相連的方式了,那我就從矩陣一開始的座標 (0, 0) 一個一個走下去,所以我就寫了兩個 for 迴圈如下,我想到的邏輯大致上就是我就開始探索,題目給出的條件也都很明確,我搜尋的路上只要有看到其他的島嶼相連,我就繼續跳過去,再慢慢走。
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
n = len(isConnected)
visited = set()
count = 0
for i in range(n):
for j in range(n):
# 開始走訪各個島嶼
...
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
n = len(isConnected)
visited = [False] * n
count = 0
def dfs(i):
# 走訪看看島嶼 i 是否與其他島嶼有連結
for j in range(n):
# 如果有連結,在之前也還沒看過的話,走過去拜訪
if isConnected[i][j] == 1 and visited[j] == False:
visited[i] = True
dfs(j)
# 走訪每一個島嶼
for i in range(n):
if visited[i] == False:
visited[i] = True
dfs(i)
count += 1
return count
時間複雜度:O(N^2)
空間複雜度:O(N)
BFS
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
n = len(isConnected)
visited = [False] * n
count = 0
queue = deque([])
for i in range(n):
if visited[i] == False:
queue.append(i)
while queue:
x = queue.popleft()
visited[x] = True
for j in range(n):
if isConnected[x][j] == 1 and visited[j] == False:
queue.append(j)
count += 1
return count
UnionFind
class UnionFind:
def __init__(self, size):
self.root = [i for i in range(size)]
self.rank = [1] * size
self.count = size
def find(self, x):
if x == self.root[x]:
return x
self.root[x] = self.find(self.root[x])
return self.root[x]
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
if self.rank[rootX] > self.rank[rootY]:
self.root[rootY] = rootX
elif self.rank[rootX] < self.rank[rootY]:
self.root[rootX] = rootY
else:
self.root[rootY] = rootX
self.rank[rootX] += 1
self.count -= 1
def getCount(self):
return self.count
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
if not isConnected or len(isConnected) == 0:
return 0
n = len(isConnected)
uf = UnionFind(n)
for i in range(n):
for j in range(n):
if isConnected[i][j] == 1:
uf.union(i, j)
return uf.getCount()