547. Number of Provinces 👍
There are n
cities. Some of them are connected, while some are not. If city a
is connected directly with city b
, and city b
is connected directly with city c
, then city a
is connected indirectly with city c
.
A province is a group of directly or indirectly connected cities and no other cities outside of the group.
You are given an n x n
matrix isConnected
where isConnected[i][j] = 1
if the ith
city and the jth
city are directly connected, and isConnected[i][j] = 0
otherwise.
Return the total number of provinces**.
Example 1:
Example 2:
Constraints:
1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j]
is1
or0
.isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]
Solution:
DFS
class Solution {
public int findCircleNum(int[][] isConnected) {
int result = 0;
int n = isConnected.length;
int m = isConnected[0].length;
boolean[] visited = new boolean[n];
for (int i = 0; i < n; i++){
if (visited[i] == false){
result++;
dfs(i, isConnected, visited);
}
}
return result;
}
/*
0 1 2 3 0-3
1 0 0 1
0 1 1 0
0 1 1 1
1 0 1 1
*/
private void dfs(int x, int[][] isConnected, boolean[] visited){
if (x < 0 || x >= isConnected.length || visited[x] == true){
return;
}
visited[x] = true;
for (int i = 0; i < isConnected.length; i++){
if (isConnected[x][i] == 1 && !visited[i]){
dfs(i, isConnected, visited);
}
}
return;
}
}
// TC: O(n^2)
// SC: O(n)
BFS
class Solution {
public int findCircleNum(int[][] isConnected) {
int result = 0;
int n = isConnected.length;
int m = isConnected[0].length;
boolean[] visited = new boolean[n];
for (int i = 0; i < n; i++){
if (visited[i] == false){
result++;
// dfs(i, isConnected, visited);
bfs(i, isConnected, visited);
}
}
return result;
}
/*
0 1 2 3 0-3
1 0 0 1
0 1 1 0
0 1 1 1
1 0 1 1
*/
private void bfs(int x, int[][] isConnected, boolean[] visited){
Deque<Integer> queue = new ArrayDeque<Integer>();
queue.offerLast(x);
visited[x] = true;
while(!queue.isEmpty()){
int cur = queue.pollFirst();
for (int i = 0; i < isConnected.length; i++){
if (isConnected[cur][i] == 1 && visited[i] == false){
queue.offerLast(i);
visited[i] = true;
}
}
}
}
}
// TC: O(n^2)
// SC: O(n)
UnionFind
class Solution {
public int findCircleNum(int[][] isConnected) {
int n = isConnected.length;
UnionFind uf = new UnionFind(n);
int result = 0;
for (int i = 0; i < n; i++){
for (int j = i + 1; j < n; j++){
if (isConnected[i][j] == 1){
uf.union(i, j); // TC: O(n)
}
}
}
for (int i = 0; i < n; i++){
if (uf.find(i) == i){ // TC: O(n)
result++;
}
}
return result;
}
}
class UnionFind{
int[] root;
public UnionFind(int size){
root = new int[size];
for (int i = 0; i < size; i++){
root[i] = i;
}
}
public int find(int x){
if (x == root[x]){
return x;
}
return root[x] = find(root[x]);
}
public void union(int x, int y){ // TC: O(n)
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY){
root[rootY] = rootX; // let X be dad
}
}
public boolean connected(int x, int y){
return find(x) == find(y);
}
}
// TC: O(n^2)
// SC: O(n)