给定一组 N 人(编号为 1, 2, …, N), 我们想把每个人分进任意大小的两组。
每个人都可能不喜欢其他人,那么他们不应该属于同一组。
形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 a 和 b 的人归入同一组。
当可以用这种方法将每个人分进两组时,返回 true;否则返回 false。
示例 1:
输入:N = 4, dislikes = [[1,2],[1,3],[2,4]]
输出:true
解释:group1 [1,4], group2 [2,3]
示例 2:
输入:N = 3, dislikes = [[1,2],[1,3],[2,3]]
输出:false
示例 3:
输入:N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
输出:false
提示:
1 <= N <= 2000
0 <= dislikes.length <= 10000
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
对于 dislikes[i] == dislikes[j] 不存在 i != j
思 路 分 析 : \color{blue}思路分析: 思路分析:这道题有点类似染色问题,首先我们需要对dislikes容器进行处理,转换为vector
,myDislike[i]存储i不喜欢的所有人。(类似图中的邻接表)
接着我们从dislikes[i]开始,如果dislikes[i][0]没有确定分组,则将它默认分组为0,将dislikes[i][1]分组为1(myDislike[i]中的所有人都需要分组1,myDislike[i]存储i讨厌的所有人)。如果在深度优先搜索的时候出现某个人与他不喜欢的人在一个分组,则直接返回false。
如果所有人都分配完成后都没有出现false,则说明能进行二分。
还有一点,可能有些道友认为默认分组为0可能会影响,为啥不默认分组为1呢?
假设能分成两个组0,1,它们各自不冲突,那可不可以把0组所有人换到1,把1组所有人换到0?
所有,如果它本身能分组,默认分0还是1是没有关系的。
class Solution {
public:
bool possibleBipartition(int N, vector<vector<int>>& dislikes) {
if (dislikes.empty()){
return true;
}
vector<int> resPartition(N + 1, -1);//resPartition[i]记录着i的分组,分组只有0,1,初始化为-1,说明是还没有分组
vector<vector<int>> myDisLike(N + 1);//myDisLike[i]记录这i所有的不喜欢的人
//将dislikes容器转换为myDisLike容器信息
for (const auto & dislike : dislikes){
myDisLike[dislike[0]].push_back(dislike[1]);
myDisLike[dislike[1]].push_back(dislike[0]);
}
//对所有的dislikes对进行处理
for (const auto & dislike : dislikes){
//检查这个不喜欢对是否处理过了
if (resPartition[dislike[0]] == -1){
//如果没有处理过,则将dislike[0]分组默认为 0
if (!dfs(myDisLike, dislike[0], 0, resPartition)){
return false;
}
}
}
return true;
}
//在person分组为partition的情况下,确定他不喜欢的人的分组,返回false说明出现了冲突
bool dfs(vector<vector<int>> &myDisLike, int person, int partition, vector<int> &resPartition){
if (resPartition[person] == -1){
//如果person还未分组,则分为partition
resPartition[person] = partition;
//则person不喜欢的所有人都应该分组为 !partition
for (const auto dislikePerson : myDisLike[person]){
if (resPartition[dislikePerson] == resPartition[person]){
//如果person和他不喜欢的dislikePerson已经在一个组
return false;
}
//深度优先处理,在dislikePerson分组!partition情况下,确定dislikePerson所不喜欢的人的分组
if (!dfs(myDisLike, dislikePerson, !partition, resPartition)){
return false;
}
}
return true;
}
else if (resPartition[person] != partition){
//如果person应该分组partition,蛋式他出现在对立组,冲突
return false;
}
return true;
}
};