547. Number of Provinces
DFS, BFS, Union Find, Graph, AMateList ·Problem Statement
link: LeetCode.cn LeetCode There are n cities. Some of them are connected, while some are not. If city a is connected directly with city b, and city b is connected directly with city c, then city a is connected indirectly with city c.
A province is a group of directly or indirectly connected cities and no other cities outside of the group.
You are given an n x n matrix isConnected where isConnected[i][j] = 1 if the ith city and the jth city are directly connected, and isConnected[i][j] = 0 otherwise.
Return the total number of provinces.
Example:
Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]]
Output: 2
Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]]
Output: 3
Solution Approach
The solution can be approached using Depth-First Search (DFS), Breadth-First Search (BFS), or Union-Find to traverse the graph represented by the adjacency matrix and count the number of connected components or provinces.
Algorithm
- Depth-First Search (DFS): Traverse the graph using DFS to mark all cities connected to a starting city as visited, and count each DFS initiation as a new province.
- Breadth-First Search (BFS): Use a queue to perform BFS, marking connected cities as visited, and count each BFS initiation as a new province.
- Union-Find: Utilize the Union-Find data structure to merge sets of connected cities and count the number of unique sets to determine the number of provinces.
Implement
class Solution:
def findCircleNum(self, isConnected):
def dfs(i):
for j in range(len(isConnected)):
if isConnected[i][j] == 1 and not visited[j]:
visited[j] = True
dfs(j)
visited = [False] * len(isConnected)
count = 0
for i in range(len(isConnected)):
if not visited[i]:
dfs(i)
count += 1
return count
class Solution:
def findCircleNum(self, isConnected):
visited = [False] * len(isConnected)
queue = deque()
count = 0
for i in range(len(isConnected)):
if not visited[i]:
queue.append(i)
while queue:
curr = queue.popleft()
visited[curr] = True
for j in range(len(isConnected)):
if isConnected[curr][j] == 1 and not visited[j]:
queue.append(j)
count += 1
return count
class UnionFind:
def __init__(self, n):
self.parents = list(range(n))
self.groupNum = n
def find(self, node):
while node != self.parents[node]:
self.parents[node] = self.parents[self.parents[node]] # Path compression
node = self.parents[node]
return node
def union(self, x, y):
xParent = self.find(x)
yParent = self.find(y)
if xParent != yParent:
self.parents[yParent] = xParent
self.groupNum -= 1
def getGroupNum(self):
return self.groupNum
class Solution:
def findCircleNum(self, isConnected):
n = len(isConnected)
unionFind = UnionFind(n)
for i in range(n):
for j in range(i + 1, n):
if isConnected[i][j] == 1:
unionFind.union(i, j)
return unionFind.getGroupNum()