class Solution:
def findCircleNum(self, isConnected):
n = len(isConnected)
visited = [False] * n
def dfs(city):
for neighbor in range(n):
if isConnected[city][neighbor] == 1 and not visited[neighbor]:
visited[neighbor] = True
dfs(neighbor)
provinces = 0
for i in range(n):
if not visited[i]:
visited[i] = True
dfs(i)
provinces += 1
return provinces
class Solution {
public:
void dfs(int city, vector<vector<int>>& isConnected, vector<bool>& visited) {
int n = isConnected.size();
for (int neighbor = 0; neighbor < n; ++neighbor) {
if (isConnected[city][neighbor] == 1 && !visited[neighbor]) {
visited[neighbor] = true;
dfs(neighbor, isConnected, visited);
}
}
}
int findCircleNum(vector<vector<int>>& isConnected) {
int n = isConnected.size();
vector<bool> visited(n, false);
int provinces = 0;
for (int i = 0; i < n; ++i) {
if (!visited[i]) {
visited[i] = true;
dfs(i, isConnected, visited);
provinces++;
}
}
return provinces;
}
};
class Solution {
public int findCircleNum(int[][] isConnected) {
int n = isConnected.length;
boolean[] visited = new boolean[n];
int provinces = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
dfs(isConnected, visited, i);
provinces++;
}
}
return provinces;
}
private void dfs(int[][] isConnected, boolean[] visited, int city) {
for (int neighbor = 0; neighbor < isConnected.length; neighbor++) {
if (isConnected[city][neighbor] == 1 && !visited[neighbor]) {
visited[neighbor] = true;
dfs(isConnected, visited, neighbor);
}
}
}
}
var findCircleNum = function(isConnected) {
const n = isConnected.length;
const visited = new Array(n).fill(false);
function dfs(city) {
for (let neighbor = 0; neighbor < n; neighbor++) {
if (isConnected[city][neighbor] === 1 && !visited[neighbor]) {
visited[neighbor] = true;
dfs(neighbor);
}
}
}
let provinces = 0;
for (let i = 0; i < n; i++) {
if (!visited[i]) {
visited[i] = true;
dfs(i);
provinces++;
}
}
return provinces;
};
The "Number of Provinces" problem asks you to determine how many groups of directly or indirectly connected cities exist, given a 2D matrix isConnected
. Each element isConnected[i][j]
is 1 if city i
and city j
are directly connected, and 0 otherwise. A province is defined as a group of cities that are directly or indirectly connected, and no other cities outside the group are connected to any city within the group.
n
cities.When first approaching the problem, you might think to check every possible pair of cities to see if they're connected, but this quickly becomes inefficient as the number of cities grows. The key realization is that the matrix represents an undirected graph, where cities are nodes and connections are edges. The problem essentially asks for the number of connected components in this graph.
Brute-force would involve repeatedly checking every possible path between cities, but this is redundant and slow. Instead, we can use graph traversal techniques such as Depth-First Search (DFS), Breadth-First Search (BFS), or Union-Find (Disjoint Set Union) to efficiently group cities and count the number of distinct provinces.
The main insight is: once we start visiting a city, we can use DFS (or BFS) to mark all cities in its province as visited, so we don't count them again.
Let's break down the steps to solve the problem using DFS (the most straightforward approach for beginners):
We use DFS here because it's easy to implement recursively and efficiently explores all connected nodes. The visited array ensures we don't revisit cities, preventing infinite loops and redundant counting.
Alternative approaches include BFS (using a queue) or Union-Find, but the core idea remains: group connected cities and count the groups.
Let's consider the following input:
isConnected = [ [1, 1, 0], [1, 1, 0], [0, 0, 1] ]
isConnected[0][1] == 1
).The O(n²) comes from the need to potentially check every connection in the matrix, but each is only processed once.
The Number of Provinces problem is a classic application of graph traversal. By treating the input matrix as an adjacency matrix for an undirected graph, we can efficiently count the number of connected components (provinces) using DFS, BFS, or Union-Find. The key insight is to mark cities as visited as we traverse, ensuring each group is counted exactly once. This approach is both intuitive and efficient, making it a staple technique in graph algorithms.