content
content
3. Method 2: Consolidate collections
1. Topic description
There is n
a city, some of which are connected to each other and others that are not. If a
the city is b
directly connected to the city b
and the city c
is directly connected to the city, then the city is indirectly connected to the a
city .c
A province is a group of directly or indirectly connected cities, excluding other unconnected cities.
Give you a n x n
matrix isConnected
, which isConnected[i][j] = 1
means that the i
th city and the j
th city are directly connected, and the isConnected[i][j] = 0
two are not directly connected.
Returns the number of provinces in the matrix .
Example 1:
Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]] Output: 2
Example 2:
Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]] Output: 3
hint:
1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j]
for1
or0
isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]
Source: LeetCode
Link: https://leetcode-cn.com/problems/number-of-provinces The
copyright belongs to LeetCode.com. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.
2. Method 1: Graph Traversal
2.1 Ideas
The translation of provinces into "province" really has to be accepted. Fortunately, this is a symbol and does not affect the solution.
In essence, it is to find the number of connected regions in a graph.
This graph is represented by an adjacency matrix represented by isConnected.
Since it is a full graph traversal, either breadth-first search or depth-first search can be dealt with. Several such topics have appeared earlier in this "Topics in Graph Theory Fundamentals" series. Refer to "Graph Theory Fundamentals" in Leetcode's daily problem-solving notes (dynamic update...) of Benniu Slow Farming .
The representation of the adjacency matrix makes it very convenient to query adjacent nodes.
2.2 Code Implementation
from typing import List
from collections import deque
class Solution:
def findCircleNum(self, isConnected: List[List[int]]) -> int:
if len(isConnected)==0:
return 0
N = len(isConnected)
islandCnt = 0
q = deque()
visited = set()
for node in range(N):
# print(node, visited)
# find the next unvisited node
if node not in visited:
# print("Start node of the next island: ", node)
# Start from this node to search the connected sub-graph
q.append(node)
visited.add(node)
while len(q) > 0:
tmp = q.pop()
for k in range(N):
if isConnected[tmp][k]==1 and k not in visited:
q.append(k)
visited.add(k)
islandCnt += 1
return islandCnt
if __name__ == '__main__':
sln = Solution()
isConnected = [[1,1,0],[1,1,0],[0,0,1]]
print(sln.findCircleNum(isConnected))
isConnected = [[1,0,0],[0,1,0],[0,0,1]]
print(sln.findCircleNum(isConnected))
The above code uses "q.pop()", which is paired with q.append(), indicating that q is used as a stack, so it represents a depth-first search. And if it is changed to "q.popleft()", it means that q is used as a queue, so that the breadth-first search is programmed.
Execution time: 44 ms, beat 88.42% of users in all Python3 commits
Memory consumption: 15.4 MB, beating 42.50% of users across all Python3 commits
3. Method 2: Consolidate collections
3.1 Ideas
Another way to calculate the number of connected components is to use union-find. Initially, each province is initialized to belong to a different connected component. Traverse the matrix isConnected, if there is a connected relationship between two provinces, they belong to the same connected component, and merge them.
After traversing all elements of the matrix isConnected, the total number of remaining connected components is the total number of provinces.
In the following implementation, groupID is used to store the ID number of the group to which the corresponding node belongs. Each province is initialized to contain only its own group on initialization. groupID is the ID or index number of each province.
Then traverse from small to large. For each province, query the node with the largest index number among its adjacent nodes, and merge itself into the group of the province with the largest index number. In the end, the number of provinces whose group number has not changed is the last remaining group number, which is the number of provinces required in this question.
3.2 Code Implementation
class Solution:
def findCircleNum_union_find(self, isConnected: List[List[int]]) -> int:
def find(index: int) -> int:
# Find the group to which the index belongs
if groupID[index] != index:
groupID[index] = find(groupID[index])
return groupID[index]
def union(index1: int, index2: int):
# Join index1 into the group which index2 belongs to
groupID[find(index1)] = find(index2)
# Initialization.
# Start from the state in which each province belongs to the own-group
# Each group has one province with the same index as its initial root.
groupID = list(range(len(isConnected)))
# For each group, find the (directly or indirectly) connected province and
# join itself into the later group
for i in range(len(isConnected)):
for j in range(i + 1, len(isConnected)):
if isConnected[i][j] == 1:
union(i, j)
numGroup = sum(groupID[i] == i for i in range(len(isConnected)))
return numGroup
Execution time: 56 ms, beating 44.57% of users across all Python3 commits
Memory consumption: 15.3 MB, beating 54.80% of users across all Python3 commits
Back to the main directory: Leetcode daily problem-solving notes (dynamic update...)