处理含限制条件的好友请求
难度:
标签:
题目描述
代码结果
运行时间: 203 ms, 内存: 17.2 MB
/*
思路:
1. 使用并查集(Union-Find)来跟踪朋友关系。
2. 对于每个请求,检查两个用户是否可以成为朋友,即它们的根节点是否会违反任何限制。
3. 如果没有违反限制,则合并两个用户。
4. 返回请求是否成功的布尔数组。
5. 使用Java Stream API处理数组。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
class Solution {
private int[] parent;
private int[] rank;
public boolean[] friendRequests(int n, int[][] restrictions, int[][] requests) {
parent = IntStream.range(0, n).toArray();
rank = new int[n];
Arrays.fill(rank, 1);
return IntStream.range(0, requests.length)
.mapToObj(i -> {
int u = requests[i][0];
int v = requests[i][1];
int pu = find(u);
int pv = find(v);
if (pu == pv) return true;
boolean canBeFriends = Arrays.stream(restrictions)
.noneMatch(restriction -> {
int r1 = find(restriction[0]);
int r2 = find(restriction[1]);
return (pu == r1 && pv == r2) || (pu == r2 && pv == r1);
});
if (canBeFriends) {
union(u, v);
}
return canBeFriends;
})
.mapToBoolean(Boolean::booleanValue)
.toArray();
}
private int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
private void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
}
解释
方法:
此题解使用了两个字典 `fri` 和 `res` 来存储朋友关系和限制条件。其中 `fri` 的键是用户编号,值是该用户的朋友集合;`res` 的键是用户编号,值是与该用户存在限制的用户集合。处理好友请求时,如果两个用户已经是直接朋友,则请求成功;如果两用户之间存在间接限制,请求失败;否则,更新双方的朋友集和限制集,并将新的朋友关系传播到相关用户,最后标记此请求为成功。
时间复杂度:
O(m * n)
空间复杂度:
O(n^2)
代码细节讲解
🦆
在算法中,如何保证当更新一个用户的朋友集和限制集后,相关联的用户集也能同步更新?
▷🦆
题解中提到处理好友请求时会检查间接限制,具体是如何检查两个用户之间是否存在间接限制的?
▷🦆
题解中使用了集合合并操作来处理好友关系,这对算法的效率有什么影响?是否存在更优的数据结构来处理此类操作?
▷🦆
解题思路中未提及如何处理多重间接关系,例如A与B是朋友,B与C是朋友,但A与C不能是朋友的情况。算法如何解决这种复杂的间接限制?
▷