第一百零五天:力扣1489题,找到最小生成树里的关键边和伪关键边
地址:leetcode-cn.com/problems/fi…
思路:kruskal算法 + 并查集。头疼题,照抄题。
/**
* @param {number} n
* @param {number[][]} edges
* @return {number[][]}
*/
var findCriticalAndPseudoCriticalEdges = function(n, edges) {
// 思路,最小生成树(kruskal算法)
// 1.记录边的初始索引号,再排序(因为返回的结果要用索引来标示边)
// 2.首先使用kruskal算法算出最小生成树的权值和minCosts
// 3.找关键边:去除某条边后跑kruskal算法,如果其最小生成树的权值和比minCosts大,或者不连通,那么这条边就是关键边
// 4.找伪关键边:如果某条边不是关键边,那么如果将这条边一定包含在最小生成树里面后,其权值仍然和minCosts一样,则这条边就是伪关键边
// 1.记录初始索引号,排序
for(let i = 0; i < edges.length; i++) {
edges[i].push(i);
}
edges.sort((a, b) => a[2] - b[2]);
// 2.使用kruskal算法先算出minCosts
let minCosts = MST(-1, false); // 这里用-1和false来标示不对任何一条边进行指示
// 3.4.找关键边和伪关键边
const ans = [[], []];
for(let k = 0; k < edges.length; k++) {
if(MST(k, false) > minCosts) ans[0].push(edges[k][3]); // 这条边是关键边,则加入边对应的初始索引号
else if(MST(k, true) === minCosts) ans[1].push(edges[k][3]); // 这条边是伪关键边
}
// 定义kruskal算法
function MST(k, hasK) { // k标示对第k条边进行操作,hasK标示是要包含第k条边还是要去除第k条边
let cost = 0, count = 0;
const unionFindSet = new UnionFind(n);
// 如果一定要包含第k条边,则先加上
if(hasK) {
unionFindSet.union(edges[k][0], edges[k][1]);
cost += edges[k][2];
count++;
}
// 遍历排序后的边
for(let i = 0; i < edges.length; i++) {
if(!hasK && i === k) continue; // 如果一定不包含第k条边,则判断是不包含而且i===k时跳过
if(!unionFindSet.union(edges[i][0], edges[i][1])) { // 连通了两个相异的连通量
cost += edges[i][2];
count++;
if(count === n - 1) break; // 已经全部连上了,则退出
}
}
return count === n - 1 ? cost : Infinity; // 判断是否可以连通,可以则返回权值和,不可以则返回一个无穷大
}
return ans;
};
// 定义并查集
class UnionFind {
constructor(n) {
this.parents = Array(n).fill(0).map((value, index) => index);
this.ranks = Array(n).fill(0);
}
find(x) {
if(this.parents[x] !== x) {
this.parents[x] = this.find(this.parents[x]);
}
return this.parents[x];
}
union(x, y) {
let rootX = this.find(x), rootY = this.find(y);
if(rootX === rootY) return true;
if(this.ranks[rootX] > this.ranks[rootY]) {
this.parents[rootY] = rootX;
} else if(this.ranks[rootX] < this.ranks[rootY]) {
this.parents[rootX] = rootY;
} else {
this.parents[rootY] = rootX;
this.ranks[rootX]++;
}
return false;
}
}
执行用时:208 ms, 在所有 JavaScript 提交中击败了66.67%的用户
内存消耗:46.9 MB, 在所有 JavaScript 提交中击败了33.33%的用户
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!