Number of Provinces
Problem statement
There are n cities. You get an n x n matrix isConnected where isConnected[i][j] = 1 means city i and city j are directly connected, and 0 means they are not. The matrix is symmetric and every city is connected to itself.
Connection is transitive: if a connects to b and b connects to c, all three are in the same group. A province is one such group. Return the number of provinces.
Examples
Example 1
Input: isConnected = [[1, 0, 0, 1],
[0, 1, 1, 0],
[0, 1, 1, 0],
[1, 0, 0, 1]]
Output: 2
Explanation: Cities 0 and 3 form one province, cities 1 and 2 form the other.
Example 2
Input: isConnected = [[1, 1, 0],
[1, 1, 1],
[0, 1, 1]]
Output: 1
Explanation: Cities 0 and 2 are not linked directly, but both link to city 1, so all three form one province.
Hints
Approach
Depth-first search straight off the matrix. Each time you meet an unvisited city, it starts a new province; visit everything reachable from it.
- Keep a
visitedarray. - For each city not yet visited, add one to the count, mark it visited and push it on a stack.
- Pop a city, scan its row, and push every unvisited
otherwithisConnected[city][other] == 1, marking it visited as you push. - When the stack empties, that province is fully visited.
Every city is popped once and each pop scans one row of length n, giving exactly O(n^2). The input itself has n^2 cells, so nothing can do better. The explicit stack avoids recursion limits.
O(n^2)Space O(n)class Solution: def findCircleNum(self, isConnected: list[list[int]]) -> int: n = len(isConnected) visited = [False] * n provinces = 0 for start in range(n): if visited[start]: continue provinces += 1 visited[start] = True stack = [start] while stack: city = stack.pop() for other in range(n): if isConnected[city][other] and not visited[other]: visited[other] = True stack.append(other) return provincesFollow-up questions
- Return the members of each province, not just the count.
- Links are removed over time instead of added. How would you track the province count then?
Frequently asked questions
On a full adjacency matrix both must read all n^2 cells, and DFS does it with a plain array and no extra factor. Union-find earns its place when links arrive one at a time, or when the input is an edge list too large to store as a matrix.
It is counting network partitions. Given which hosts can reach which, how many isolated groups are there? The same question appears when checking whether a cluster has split into halves that cannot see each other, or finding which subnets are joined through peering.