# LC 547. Number of Provinces ### [Problem link](https://leetcode.com/problems/number-of-provinces/) ###### tags: `leedcode` `python` `c++` `medium` `Union Find` `DFS` There are <code>n</code> cities. Some of them are connected, while some are not. If city <code>a</code> is connected directly with city <code>b</code>, and city <code>b</code> is connected directly with city <code>c</code>, then city <code>a</code> is connected indirectly with city <code>c</code>. A **province** is a group of directly or indirectly connected cities and no other cities outside of the group. You are given an <code>n x n</code> matrix <code>isConnected</code> where <code>isConnected[i][j] = 1</code> if the <code>i<sup>th</sup></code> city and the <code>j<sup>th</sup></code> city are directly connected, and <code>isConnected[i][j] = 0</code> otherwise. Return the total number of **provinces** . **Example 1:** <img alt="" src="https://assets.leetcode.com/uploads/2020/12/24/graph1.jpg" style="width: 222px; height: 142px;" /> ``` Input: isConnected = [[1,1,0],[1,1,0],[0,0,1]] Output: 2 ``` **Example 2:** <img alt="" src="https://assets.leetcode.com/uploads/2020/12/24/graph2.jpg" style="width: 222px; height: 142px;" /> ``` Input: isConnected = [[1,0,0],[0,1,0],[0,0,1]] Output: 3 ``` **Constraints:** - <code>1 <= n <= 200</code> - <code>n == isConnected.length</code> - <code>n == isConnected[i].length</code> - <code>isConnected[i][j]</code> is <code>1</code> or <code>0</code>. - <code>isConnected[i][i] == 1</code> - <code>isConnected[i][j] == isConnected[j][i]</code> ## Solution 1 - Union Find #### Python ```python= class UnionFind: def __init__(self, size): self.root = list(range(size)) self.rank = [1] * size self.provinces = size def find(self, x): if self.root[x] != x: self.root[x] = self.find(self.root[x]) return self.root[x] def union(self, x, y): rootX = self.find(x) rootY = self.find(y) if rootX != rootY: if self.rank[rootX] > self.rank[rootY]: self.root[rootY] = rootX elif self.rank[rootX] < self.rank[rootY]: self.root[rootX] = rootY else: self.root[rootY] = rootX self.provinces -= 1 def getProvinces(self): return self.provinces class Solution: def findCircleNum(self, isConnected: List[List[int]]) -> int: n = len(isConnected) uf = UnionFind(n) for i in range(n): for j in range(i+1, n): if isConnected[i][j]: uf.union(i, j) return uf.getProvinces() ``` #### C++ ```cpp= class UnionFind { public: UnionFind(int size) : root(size), rank(size) { for (int i = 0; i < size; i++) { root[i] = i; rank[i] = 1; } } int find(int x) { if (x == root[x]) { return x; } return root[x] = find(root[x]); } void unionSet(int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (rank[rootX] > rank[rootY]) { root[rootY] = root[rootX]; } else if (rank[rootX] < rank[rootY]) { root[rootX] = root[rootY]; } else { root[rootY] = root[rootX]; rank[rootX] += 1; } } } bool isConnected(int x, int y) { return find(x) == find(y); } private: vector<int> root; vector<int> rank; }; class Solution { public: int findCircleNum(vector<vector<int>>& isConnected) { UnionFind uf(isConnected.size()); int ans = isConnected.size(); for (int i = 0; i < isConnected.size(); i++) { for (int j = 0; j < isConnected[i].size(); j++) { if (isConnected[i][j] && uf.isConnected(i, j) == false) { ans--; uf.unionSet(i, j); } } } return ans; } }; ``` ## Solution 2 - DFS #### Python ```python= class Solution: def findCircleNum(self, isConnected: List[List[int]]) -> int: n = len(isConnected) seen = set() res = 0 for i in range(n): if i in seen: continue res += 1 q = deque([i]) seen.add(i) while q: cur = q.pop() for nei in range(n): if isConnected[cur][nei] and nei not in seen: q.append(nei) seen.add(nei) return res ``` #### C++ ```cpp= class Solution { public: void dfs(vector<vector<int>>& isConnected, vector<int>& seen, int i) { seen[i] = 1; for (int j = 0; j < isConnected.size(); j++) { if (i != j && isConnected[i][j] == 1 && seen[j] == 0) { dfs(isConnected, seen, j); } } } int findCircleNum(vector<vector<int>>& isConnected) { int n = isConnected.size(); vector<int> seen(n, 0); int ans = 0; for (int i = 0; i < n; i++) { if (seen[i] == 0) { ans++; dfs(isConnected, seen, i); } } return ans; } }; ``` >### Complexity >| | Time Complexity | Space Complexity | >| ----------- | --------------- | ---------------- | >| Solution 1 | O($n^2$) | O(n) | >| Solution 2 | O($n^2$) | O(n) | ## Note x