Keshawn_lu's Blog

Leetcode 886. 可能的二分法

字数统计: 509阅读时长: 2 min
2022/10/16 Share

题目简介:

给定一组 n 人(编号为 1, 2, ..., n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。

给定整数 n 和数组 dislikes ,其中 dislikes[i] = [ai, bi] ,表示不允许将编号为 aibi的人归入同一组。当可以用这种方法将所有人分进两组时,返回 true;否则返回 false

示例 1:

1
2
3
输入:n = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]

示例 2:

1
2
输入:n = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false

提示:

  • 1 <= n <= 2000
  • 0 <= dislikes.length <= 10^4
  • dislikes[i].length == 2
  • 1 <= dislikes[i][j] <= n
  • ai < bi
  • dislikes 中每一组都 不同

思路:

使用并查集,初始化假设每个人只能和自己分到一起(每个人的祖先都是自己)。

然后依次遍历每个人不喜欢的人,若自己与不喜欢的人分到了一起(祖先相同),则返回false

否则,将其不喜欢的人都分到同一组(祖先都为同一个)。

若最后无冲突,则返回true

代码如下:

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
class Solution {
public:
bool possibleBipartition(int n, vector<vector<int>>& dislikes) {

vector<int> p(n + 1);
iota(p.begin(), p.end(), 0); //假设每个人只和自己在一起

function<int(int)> find = [&](int x) -> int {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
};

vector<vector<int>> graph(n + 1, vector<int>()); //记录每个人不喜欢的人
for(int i = 0; i < dislikes.size(); i++){

graph[dislikes[i][0]].push_back(dislikes[i][1]);
graph[dislikes[i][1]].push_back(dislikes[i][0]);
}

for(int i = 0; i < n; i++){

for(int j = 0; j < graph[i + 1].size(); j++){

if(find(i + 1) == find(graph[i + 1][j])) //自己和不喜欢的人分到了一组
return false;

p[find(graph[i + 1][j])] = find(graph[i + 1][0]); //将不喜欢的人都分到一组,祖先统一为不喜欢的第一个人的祖先
}
}

return true;
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: