携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情 >>
处理含限制条件的好友请求
给你一个整数 n ,表示网络上的用户数目。每个用户按从 0 到 n - 1 进行编号。
给你一个下标从 0 开始的二维整数数组 restrictions ,其中 restrictions[i] = [xi, yi] 意味着用户 xi 和用户 yi 不能 成为 朋友 ,不管是 直接 还是通过其他用户 间接 。
最初,用户里没有人是其他用户的朋友。给你一个下标从 0 开始的二维整数数组 requests 表示好友请求的列表,其中 requests[j] = [uj, vj] 是用户 uj 和用户 vj 之间的一条好友请求。
如果 uj 和 vj 可以成为 朋友 ,那么好友请求将会 成功 。每个好友请求都会按列表中给出的顺序进行处理(即,requests[j] 会在 requests[j + 1] 前)。一旦请求成功,那么对所有未来的好友请求而言, uj 和 vj 将会 成为直接朋友 。
返回一个 布尔数组 result ,其中元素遵循此规则:如果第 j 个好友请求 成功 ,那么 result[j] 就是 true ;否则,为 false 。
注意:如果 uj 和 vj 已经是直接朋友,那么他们之间的请求将仍然 成功 。
示例1:
输入:n = 3, restrictions = [[0,1]], requests = [[0,2],[2,1]]
输出:[true,false]
解释:
请求 0 :用户 0 和 用户 2 可以成为朋友,所以他们成为直接朋友。
请求 1 :用户 2 和 用户 1 不能成为朋友,因为这会使 用户 0 和 用户 1 成为间接朋友 (1--2--0) 。
示例2:
输入:n = 3, restrictions = [[0,1]], requests = [[1,2],[0,2]]
输出:[true,false]
解释:
请求 0 :用户 1 和 用户 2 可以成为朋友,所以他们成为直接朋友。
请求 1 :用户 0 和 用户 2 不能成为朋友,因为这会使 用户 0 和 用户 1 成为间接朋友 (0--2--1) 。
示例3:
输入:n = 5, restrictions = [[0,1],[1,2],[2,3]], requests = [[0,4],[1,2],[3,1],[3,4]]
输出:[true,false,true,false]
解释:
请求 0 :用户 0 和 用户 4 可以成为朋友,所以他们成为直接朋友。
请求 1 :用户 1 和 用户 2 不能成为朋友,因为他们之间存在限制。
请求 2 :用户 3 和 用户 1 可以成为朋友,所以他们成为直接朋友。
请求 3 :用户 3 和 用户 4 不能成为朋友,因为这会使 用户 0 和 用户 1 成为间接朋友 (0--4--3--1) 。
提示:
- 2 <= n <= 1000
- 0 <= restrictions.length <= 1000
- restrictions[i].length == 2
- 0 <= xi, yi <= n - 1
- xi != yi
- 1 <= requests.length <= 1000
- requests[j].length == 2
- 0 <= uj, vj <= n - 1
- uj != vj
解题思路:
1. 创建并查集;
2. 按编号添加人员;
3. 每次添加好友关系[t1,t2],遍历老死不相往来关系表restrictions,如果正好位于他们所在的两个集合,则好友关系不能建立;
4. 否则,合并这两个集合。
我的答案:
/**
* @param {number} n
* @param {number[][]} restrictions
* @param {number[][]} requests
* @return {boolean[]}
*/
var friendRequests = function(n, restrictions, requests) {
let djSet = new DisjointSet([]);
for (let i=0; i<n; i++) {
djSet.add(i);
}
function isSafe(t1,t2) {
let tt1 = djSet.findParent(t1);
let tt2 = djSet.findParent(t2);
for (let [s1,s2] of restrictions) {
let ss1 = djSet.findParent(s1);
let ss2 = djSet.findParent(s2);
if ((ss1 === tt1 && ss2 === tt2) || (ss1 === tt2 && ss2 === tt1)) return false;
}
return true;
}
let res = [];
for (let [t1,t2] of requests) {
if ( isSafe(t1,t2) ) {
res.push(true);
djSet.merge(t1,t2);
} else {
res.push(false);
}
}
return res;
};
class DisjointSet {
constructor() {
this.map = new Map();
}
findParent(v) {
let p = this.map.get(v).parent;
if (p === v) return v;
// 路径压缩
let pp = this.findParent(p);
this.map.get(v).parent = pp;
return pp;
}
add(v) {
if (!this.map.has(v)) {
this.map.set(v, {
parent: v,
rank: 1,
});
}
}
merge(v1, v2) {
let r1 = this.findParent(v1);
let r2 = this.findParent(v2);
if (r1 === r2) return;
// 按高度合并
let rank1 = this.map.get(r1);
let rank2 = this.map.get(r2);
if (rank1 < rank2) {
this.map.get(r1).parent = r2;
} else {
this.map.get(r2).parent = r1;
}
if (rank1 === rank2) {
this.map.get(r1).rank += 1;
}
}
}
最后
如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )