Browse curriculum

Number of Provinces

Count the provinces, groups of cities connected directly or through each other, in an adjacency matrix by running one DFS from every city not yet visited.

Problem Understanding

Number of Provinces (LeetCode 547): there are n cities, and isConnected[i][j] = 1 when cities i and j are directly connected. A province is a group of cities connected directly or through other cities, with no city outside the group connected to it. Return the number of provinces.

Examples: [[1,1,0],[1,1,0],[0,0,1]] → 2; [[1,0,0],[0,1,0],[0,0,1]] → 3.

The Intuition: One Province per Fresh Start

A province is a connected component of the city graph, so count components:

  1. Scan the cities in order.
  2. An unvisited city starts a new province. Every city in it is still unvisited, because none could have been reached before.
  3. DFS from it and mark everything it reaches, directly or through other cities.

The same counting idea on a grid is Number of Islands, and union-find counts the same components in Number of Operations to Make Network Connected.

Interactive Walkthrough

COLOUR = PROVINCE · GREEN = CONNECTION THE DFS WALKED

SCAN THE CITIES

city

:

provinces

0

 

7 cities, 4 direct connections. Scan the cities in order

Next

City 0 is not visited yet: it starts province 1. DFS from it

Free preview: the first 3 of 9 steps

connections

n

7

Each DFS paints one province a colour; green edges are the connections it walked. Try Through others: two cities with no direct connection still end up in one province.

Dry Run Table

Input: 7 cities, connections 0-1, 1-3, 3-2, 4-5.

Scan Action Provinces
city 0 unvisited: start province 1, DFS reaches 1, 3, 2 1
cities 1-3 already visited 1
city 4 unvisited: start province 2, DFS reaches 5 2
city 5 already visited 2
city 6 unvisited: start province 3, no connections 3

Answer: 3.

The Solution Template

A visited array and one DFS per unvisited city.

Number of Provinces Code
1var findCircleNum = function(isConnected) {
2 const n = isConnected.length;
3 const visited = new Array(n).fill(false);
4 const dfs = (u) => {
5 for (let v = 0; v < n; v++) {
6 if (isConnected[u][v] && !visited[v]) {
7 visited[v] = true;
8 dfs(v);
9 }
10 }
11 };
12 let provinces = 0;
13 for (let i = 0; i < n; i++) {
14 if (!visited[i]) {
15 provinces++;
16 visited[i] = true;
17 dfs(i);
18 }
19 }
20 return provinces;
21};

Edge Cases & Common Mistakes

  • No connections (identity matrix): every city is its own province, the answer is n.
  • Everything connected: one province.
  • Counting direct connections only: cities joined through a third city are in the same province; the DFS must follow chains.
  • Forgetting the diagonal: isConnected[i][i] is always 1, which is harmless because city i is already visited.
  • Counting inside the DFS: count only at the start of each new DFS, not per visited city.

Summary

Scan the cities; each unvisited one starts a new province and a DFS over its matrix row marks everything reachable. The number of starts is the answer. O(n²) time, O(n) space.

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Scan

    Go through the cities 0 to n − 1, with a visited array.

  2. New province

    At each unvisited city, add one province and mark it visited.

  3. Spread

    DFS from it over the matrix row, marking every connected unvisited city; return the count at the end.

Frequently asked questions

Why does counting DFS starts give the number of provinces?

One DFS marks every city reachable from its start, which is exactly one province. The scan only starts a new DFS at a city nothing has reached yet, so it starts exactly once per province.


Why is it O(n²) and not O(V + E)?

The input is an n × n matrix, so checking a city's neighbours means scanning its whole row. Every row is scanned once (each city is visited once), giving n · n checks. Converting to an adjacency list first would also cost O(n²).


Can I use union-find instead?

Yes. Start with n sets and union i and j for every isConnected[i][j] = 1 above the diagonal; each successful union removes one set. The number of sets left is the answer. It is the same count, and the method of Number of Operations to Make Network Connected.


Is this the same as Number of Connected Components?

Yes, with a different input format: LeetCode 323 gives an edge list, this problem gives an adjacency matrix. Both count connected components of an undirected graph.

New to the technique behind this problem? Watch it run step by step:

Topological Sort Visualization

Applying for software engineering roles? Free, no sign-up:

AI resume checker: match your resume to the job description