思路:将一个深林合并成一颗大树的过程。
1. 将边按照权重升序排列。
2. 遍历边,如果发现该边两端的结点不属于一个集合,那么将该边放入结果集合中。
leetcode 1584. 连接所有点的最小费用:https://leetcode-cn.com/problems/min-cost-to-connect-all-points/
/**
* @param {number[][]} points
* @return {number}
*/
var minCostConnectPoints = function(points) {
let e = [];
let parent = [];
let rank = [];
let price = 0;
for (let i = 0; i < points.length; i ++) {
//初始每个点的父结点为-1 没有父结点 每个结点生成的树高度为0
parent.push(-1);
rank.push(0);
for (let j = 0; j < i; j ++) {
if (i === j) {
continue;
}
e.push([i, j, distance(points[i], points[j])]);
}
}
//将e按照曼哈顿距离从小到大排序
e.sort((a, b) => {
return (a[2] - b[2]);
})
for (let i = 0; i < e.length; i ++) {
let res = union(e[i][0], e[i][1], parent, rank);
if (res === -1) {
continue;
}
price += e[i][2];
}
return price;
};
const distance = (point1, point2) => {
return (Math.abs(point1[0] - point2[0]) + Math.abs(point1[1] - point2[1]));
}
//找改点的根结点
const find = (i, parent) => {
root = i;
while (parent[root] !== -1) {
root = parent[root];
}
return root;
}
const union = (x, y, parent, rank) => {
let x_root = find(x, parent);
let y_root = find(y, parent);
if (x_root === y_root) {
//发现环
return -1;
} else if (x_root.rank > y_root.rank) {
parent[y_root] = x_root;
} else if (x_root.rank < y_root.rank) {
parent[x_root] = y_root;
} else {
parent[y_root] = x_root;
rank[x_root] ++;
}
//将x和y合并
return 1;
}