LeetCode 0886. 可能的二分法
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 0886. 可能的二分法相关的知识,希望对你有一定的参考价值。
【LetMeFly】886.可能的二分法:图搜索
力扣题目链接:https://leetcode.cn/problems/possible-bipartition/
给定一组 n
人(编号为 1, 2, ..., n
), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。
给定整数 n
和数组 dislikes
,其中 dislikes[i] = [ai, bi]
,表示不允许将编号为 ai
和 bi
的人归入同一组。当可以用这种方法将所有人分进两组时,返回 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 <= 104
dislikes[i].length == 2
1 <= dislikes[i][j] <= n
ai < bi
dislikes
中每一组都 不同
方法一:广度优先搜索
可以把题目理解为: n n n个节点的无向图,其中 d i s l i k e s dislikes dislikes为边
这样,我们就能很容易地把图构建出来:
vector<vector<int>> graph(n + 1);
for (auto& v : dislikes)
graph[v[0]].push_back(v[1]);
graph[v[1]].push_back(v[0]);
图构建完毕后,对图进行搜索。
因为图可能不连通,因此当发现一个新的图的节点时,用哈希表记录下这个连通子图中的节点。
这样,在图遍历过程中,我们就可以很容易地知道是否出现了“环”
遍历过程中,我们给节点编号(分组),编号只有“1”和“2”
如果某个节点的相邻节点已有编号,就看这两个节点的编号是否相同。
若相邻两个节点编号相同,则分组失败,返回false
若图成功遍历完毕,则返回true
- 时间复杂度 O ( n + m ) O(n + m) O(n+m),其中 n n n是节点个数, m m m是边的个数
- 空间复杂度 O ( n + m ) O(n + m) O(n+m)
AC代码
C++
class Solution
public:
bool possibleBipartition(int n, vector<vector<int>>& dislikes)
// 建图
vector<vector<int>> graph(n + 1);
for (auto& v : dislikes)
graph[v[0]].push_back(v[1]);
graph[v[1]].push_back(v[0]);
// 遍历
vector<bool> visited(n + 1, false); // visited[i]表示节点i是否被遍历过
vector<int> node(n + 1); // node[i]表示节点i的编号
for (int i = 1; i <= n; i++) // 查看每一个节点
if (!visited[i]) // 若是一个未遍历过的新节点,则说明这是一个新的“子图”的节点
visited[i] = true; // 标记为遍历过
node[i] = 1; // 赋编号
unordered_set<int> appeared; // 用来记录这个子图中都有哪些节点
appeared.insert(i);
queue<int> q; // 广搜队列
q.push(i);
while (q.size())
int thisNode = q.front(); // 取出节点
q.pop();
for (int toNode : graph[thisNode]) // 节点临边
if (!visited[toNode]) // 第一次遍历到
visited[toNode] = true;
node[toNode] = node[thisNode] == 1 ? 0 : 1;
appeared.insert(toNode);
q.push(toNode);
else
if (appeared.count(toNode)) // 这俩点相连
if (node[thisNode] == node[toNode])
return false; // !!!!!!!!
return true;
;
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/127344544
以上是关于LeetCode 0886. 可能的二分法的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 886 可能的二分法[dfs] HERODING的LeetCode之路