文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 DFS
    • 2.2 BFS
    • 2.3 并查集

1. 题目

给定一组 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/possible-bipartition
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 把人分成2组,组内没有自己不喜欢的人

2.1 DFS

着色法,初始颜色均为0,着色成1或者2,遇到矛盾的返回 false

class Solution {unordered_map<int,unordered_set<int>> m;bool ans = true;
public:bool possibleBipartition(int N, vector<vector<int>>& dislikes) {if(dislikes.size() <= 2) return true;vector<int> color(N+1, 0);for(auto& d : dislikes)//建图{m[d[0]].insert(d[1]);m[d[1]].insert(d[0]);}for(int i = 1; i <= N; i++){if(color[i] == 0)//未着色的{color[i] = 1;//着色为1dfs(i, 1, color);if(!ans)return false;}}return true;}void dfs(int id, int col, vector<int> &color){if(!ans) return;int nextcol = col==1 ? 2 : 1;//跟我相连的(不喜欢的人)颜色相反for(auto it = m[id].begin(); it != m[id].end(); it++){if(color[*it] == col)//颜色相同,出错ans = false;if(color[*it] == 0)//没有访问过的,继续着色{color[*it] = nextcol;dfs(*it, nextcol, color);}}}
};

528 ms 71.3 MB

2.2 BFS

  • 思路跟dfs一样,实现形式不一样而已
class Solution {unordered_map<int,unordered_set<int>> m;
public:bool possibleBipartition(int N, vector<vector<int>>& dislikes) {if(dislikes.size() <= 2) return true;vector<int> color(N+1, 0);for(auto& d : dislikes)//建图{m[d[0]].insert(d[1]);m[d[1]].insert(d[0]);}queue<int> q;int id, col = 1, nextcol, size;for(int i = 1; i <= N; i++){if(color[i] == 0)//未访问的{color[i] = 1;//着色为1col = 1;q.push(i);while(!q.empty()){size = q.size();nextcol = col==1 ? 2 : 1;//下一层颜色需要变while(size--){id = q.front();q.pop();for(auto it = m[id].begin(); it != m[id].end(); it++){    //相连的,不喜欢的,颜色不能一样if(color[*it] == col)return false;if(color[*it] == 0){color[*it] = nextcol;//没访问的,不喜欢的,颜色跟我不一样q.push(*it);}}}col = col==1? 2 : 1;//换颜色}}}return true;}
};

524 ms 70.9 MB

2.3 并查集

  • 参考 数据结构–并查集(Disjoint-Set)

类似题目:
LeetCode 684. 冗余连接(并查集)
LeetCode 990. 等式方程的可满足性(并查集)
LeetCode 959. 由斜杠划分区域(并查集)
LeetCode 1202. 交换字符串中的元素(并查集)
LeetCode 1319. 连通网络的操作次数(BFS/DFS/并查集)
程序员面试金典 - 面试题 17.07. 婴儿名字(并查集)

参考了题解区大佬们的思路

  • 把并查集大小开到2倍的N,左边是自己的颜色,右边是自己不喜欢的另一种颜色
  • 当a,b互斥时,a 与 b 对应的相反颜色 b+N 应该是一致的,进行merge(a, b+N)
  • 同理,merge(b, a+N)

class dsu
{vector<int> f;
public:dsu(int n){f.resize(n+1);for(int i = 0; i < n+1; ++i)f[i] = i;}void merge(int a, int b){int fa = find(a), fb = find(b);f[fa] = fb;}int find(int a)//循环+路径压缩{int origin = a;while(a != f[a])a = f[a];return f[origin] = a;//路径压缩}
};
class Solution {public:bool possibleBipartition(int N, vector<vector<int>>& dislikes) {if(dislikes.size() <= 2) return true;dsu u(2*N+1);int a, b, da, db;for(auto& d : dislikes){a = d[0];b = d[1];da = a+N;//a的另外一种颜色db = b+N;//b的另外一种颜色if(u.find(a) == u.find(b))return false;u.merge(a,db);//a跟b互斥,那么a跟b的反是一样的颜色u.merge(b,da);//同理}return true;}
};

256 ms 39.6 MB

LeetCode 886. 可能的二分法(着色DFS/BFS/拓展并查集)相关推荐

  1. 小花梨判连通(DFS或BFS或并查集+vector+map)——“美登杯”上海市高校大学生程序设计邀请赛 (华东理工大学)

    (https://acm.ecnu.edu.cn/contest/173/problem/C/) 题目大意: 小花梨给出?个点,让?位同学对这?个点任意添加无向边,构成?张图.小花梨想知道对于每个点? ...

  2. Leetcode一起攻克搜索(BFS,DFS,回溯,并查集)

    文章目录 BFS简介 DFS简介 回溯简介 并查集简介 DFS题目 690. 员工的重要性 1.dfs解法: 2.bfs算法 547.朋友圈 dfs解法 200.岛屿数量 dfs解法 417.太平洋大 ...

  3. 第 254 场力扣周赛(KMP、贪心、快速幂、二分+多源bfs、并查集 + 时光倒流)

    第 254 场力扣周赛 稀里糊涂双眼双眼惺忪的做了三道,错了4次...还是600来名 5843. 作为子字符串出现在单词中的字符串数目 题目描述 给你一个字符串数组 patterns 和一个字符串 w ...

  4. 图论-欧拉图-欧拉回路-Euler-Fluery-Hierholzer-逐步插入回路法-DFS详解-并查集

    欧拉图性质: 1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数): 2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点: 3.有向连通图D是欧拉图,当且仅当该图 ...

  5. LeetCode 2076. 处理含限制条件的好友请求(并查集)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数 n ,表示网络上的用户数目.每个用户按从 0 到 n - 1 进行编号. 给你一个下标从 0 开始的二维整数数组 restrictions ...

  6. LeetCode 1258. 近义词句子(哈希+并查集+排序+回溯)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个近义词表 synonyms 和一个句子 text , synonyms 表中是一些近义词对 ,你可以将句子 text 中每个单词用它的近义词来替换 ...

  7. UVA 11165 - Galactic Travel(BFS+twopointer+并查集)

    UVA 11165 - Galactic Travel 题目链接 题意:给定一些不能走的边,要求出从s到t的最短路 思路:由于点数多,直接广搜会超时,所以加上优化,已经找过的点就不在重复找了,这点可以 ...

  8. LeetCode 248. 中心对称数 III(DFS/BFS)

    文章目录 1. 题目 2. 解题 2.1 DFS 2.2 BFS 1. 题目 中心对称数是指一个数字在旋转了 180 度之后看起来依旧相同的数字(或者上下颠倒地看). 写一个函数来计算范围在 [low ...

  9. LeetCode 1490. 克隆 N 叉树(DFS/BFS)

    文章目录 1. 题目 2. 解题 2.1 DFS 2.2 BFS 1. 题目 给定一棵 N 叉树的根节点 root ,返回该树的深拷贝(克隆). N 叉树的每个节点都包含一个值( int )和子节点的 ...

最新文章

  1. Redis Key资源占用情况的可视化分析
  2. dnscapy使用——本质上是建立ssh的代理(通过dns tunnel)
  3. BIEE多层表头报表的制作方法
  4. vrf名称_如何使用VRF(可验证随机函数)在以太坊上生成随机数
  5. mysql 逻辑备份 物理备份_数据库的逻辑备份和物理备份--非RMAN
  6. 阿里P8大佬亲自讲解!朝阳java培训
  7. 在MaxCompute上分析IP来源的方法
  8. 计算机应用专业特色建设情况,【计算机应用论文】计算机应用类专业建设和革新探索(共3022字)...
  9. python 货币合适_算法之Python实现 - 001 : 换钱的最少货币数
  10. MATLAB学习笔记(十)
  11. Unity中Light Probe详解
  12. 深入研读Cache存储的计算
  13. Spring结合马士兵视频的学习经验
  14. matlab执行m文件语句,matlab 编写m文件函数
  15. Java学习之json篇——json介绍
  16. pythonfor杨辉三角,python实现杨辉三角 python实现杨辉三角的几种方法代码实例
  17. 曾经的移动应用推广八法尚能饭否?再加一法大概就事半功倍!
  18. zynq7020的arm A9核降频实录
  19. 设计公司如何做好产品设计
  20. Java技能树-RE-正则应用-目录

热门文章

  1. Hive报错:Error: FUNCTION 'NUCLEUS_ASCII' already exists. (state=X0Y68,code=30000)
  2. 关于无法加载已创建的布局文件的问题的解决方案以及已布局在对应的R文件中未生成相应ID的问题的解决
  3. 如何访问另一台电脑的共享文件夹_如何远程控制另一台电脑
  4. ARM中各始终之间的关系,FCLK HCLK PCLK的关系
  5. Delphi控件的“拿来主义”
  6. Linux CentOS7.0 (01)在Vmvare Workstation上 安装配置
  7. Web框架 Bottle 、Flask 、Tornado
  8. 如何通过对方IP地址查对方的MAC
  9. redis事务的简单介绍
  10. 在大公司天天调参数,感觉快废了~