547. 省份数量

题目来源:LeetCode 547. 省份数量

n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

示例1:

输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出:2

示例2:

输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出:3

限制:

  • 1 <= n <= 200
  • n == isConnected.length
  • n == isConnected[i].length
  • isConnected[i][j] 为 1 或 0
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

并查集解法

使用quick find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class UnionFind {
constructor(len) {
this.root = Array(len).fill(0).map((_, i) => i);
}
find(x) {
return this.root[x];
}
union(x, y) {
let rootx = this.find(x), rooty = this.find(y);
if(rootx !== rooty) {
for(let i = 0;i<this.root.length;i++) {
if(this.root[i] === rootx) this.root[i] = rooty;
}
}
}
getNums() {
return new Set(this.root).size;
}
}

var findCircleNum = function(isConnected) {
// quick find
const uf = new UnionFind(isConnected.length);
for(const [i, vals] of isConnected.entries()) {
for(const [j, val] of vals.entries()) {
if(val === 1) uf.union(i, j);
}
}
return uf.getNums();
};

基于路径压缩的按秩合并优化的「并查集」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class UnionFind {
constructor(len) {
this.root = Array(len)
.fill(0)
.map((_, i) => i);
this.rank = Array(len).fill(1);
this.size = len;
}
// 路径压缩优化版本的 find 函数
find(x) {
if (x === this.root[x]) return x;
return this.root[x] = this.find(this.root[x]);
}
// 按秩合并优化的 union 函数
union(x, y) {
let rootx = this.find(x), rooty = this.find(y);
if(rootx !== rooty) {
if(this.rank[rootx] > this.rank[rooty]) {
this.root[rooty] = rootx;
} else if(this.rank[rootx] < this.rank[rooty]) {
this.root[rootx] = rooty;
} else { // ===
this.root[rootx] = rooty;
this.rank[rooty] += 1;
}
this.size--;
}
}
}

var findCircleNum = function(isConnected) {
const n = isConnected.length;
const uf = new UnionFind(n);
for(let i = 0;i<n;i++) {
for(let j = 0;j<isConnected[i].length;j++) {
if(isConnected[i][j] === 1) uf.union(i, j);
}
}
return uf.size;
};

DFS解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @param {number[][]} isConnected
* @return {number}
*/
var findCircleNum = function(isConnected) {
let visited = new Set(),re = 0;
for(let i = 0;i<isConnected.length;i++){
if(!visited.has(i)){
dfs(isConnected,visited,i);
re++;
}
}
return re;
};
function dfs(data,visited,i){
for(let j = 0;j<data.length;j++){
if(data[i][j] === 1 && !visited.has(j)){
visited.add(j);
dfs(data,visited,j);
}
}
}
LeetCode
作者:Kart Jim
链接:https://github.com/can-dy-jack/delicate/2021/06/04/leetcode/547. 省份数量/
来源:Hexo
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
长风破浪会有时,直挂云帆济沧海