加载中...
886-可能的二分法(Possible Bipartition)
发表于:2021-12-03 | 分类: 中等
字数统计: 356 | 阅读时长: 1分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/possible-bipartition

英文原文

We want to split a group of n people (labeled from 1 to n) into two groups of any size. Each person may dislike some other people, and they should not go into the same group.

Given the integer n and the array dislikes where dislikes[i] = [ai, bi] indicates that the person labeled ai does not like the person labeled bi, return true if it is possible to split everyone into two groups in this way.

 

Example 1:

Input: n = 4, dislikes = [[1,2],[1,3],[2,4]]
Output: true
Explanation: group1 [1,4] and group2 [2,3].

Example 2:

Input: n = 3, dislikes = [[1,2],[1,3],[2,3]]
Output: false

Example 3:

Input: n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
Output: false

 

Constraints:

  • 1 <= n <= 2000
  • 0 <= dislikes.length <= 104
  • dislikes[i].length == 2
  • 1 <= dislikes[i][j] <= n
  • ai < bi
  • All the pairs of dislikes are unique.

中文题目

给定一组 N 人(编号为 1, 2, ..., N), 我们想把每个人分进任意大小的两组。

每个人都可能不喜欢其他人,那么他们不应该属于同一组。

形式上,如果 dislikes[i] = [a, b],表示不允许将编号为 ab 的人归入同一组。

当可以用这种方法将所有人分进两组时,返回 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
  • dislikes[i].length == 2
  • 1 <= dislikes[i][j] <= N
  • dislikes[i][0] < dislikes[i][1]
  • 对于 dislikes[i] == dislikes[j] 不存在 i != j

通过代码

官方题解

方法:深度优先搜索

思路

尝试将每个人分配到一个组是很自然的想法。假设第一组中的人是红色,第二组中的人是蓝色。

如果第一个人是红色的,那么这个人不喜欢的人必须是蓝色的。然后,任何不喜欢蓝色人的人都是红色的,那么任何不喜欢红色人的人都是蓝色的,依此类推。

如果在任何时候存在冲突,那么这个任务是不可能的完成的,因为从第一步开始每一步都符合逻辑。如果没有冲突,那么着色是有效的,所以答案是 true

算法

考虑由给定的 “不喜欢” 边缘形成的 N 人的图表。我们要检查这个图的每个连通分支是否为二分的。

对于每个连通的部分,我们只需试着用两种颜色对它进行着色,就可以检查它是否是二分的。如何做到这一点:将任一结点涂成红色,然后将它的所有邻居都涂成蓝色,然后将所有的邻居的邻居都涂成红色,以此类推。如果我们将一个红色结点涂成蓝色(或蓝色结点涂成红色),那么就会产生冲突。

[Q59Bm8ZT-Java]
class Solution { ArrayList<Integer>[] graph; Map<Integer, Integer> color; public boolean possibleBipartition(int N, int[][] dislikes) { graph = new ArrayList[N+1]; for (int i = 1; i <= N; ++i) graph[i] = new ArrayList(); for (int[] edge: dislikes) { graph[edge[0]].add(edge[1]); graph[edge[1]].add(edge[0]); } color = new HashMap(); for (int node = 1; node <= N; ++node) if (!color.containsKey(node) && !dfs(node, 0)) return false; return true; } public boolean dfs(int node, int c) { if (color.containsKey(node)) return color.get(node) == c; color.put(node, c); for (int nei: graph[node]) if (!dfs(nei, c ^ 1)) return false; return true; } }
[Q59Bm8ZT-Python]
class Solution(object): def possibleBipartition(self, N, dislikes): graph = collections.defaultdict(list) for u, v in dislikes: graph[u].append(v) graph[v].append(u) color = {} def dfs(node, c = 0): if node in color: return color[node] == c color[node] = c return all(dfs(nei, c ^ 1) for nei in graph[node]) return all(dfs(node) for node in range(1, N+1) if node not in color)

复杂度分析

  • 时间复杂度:$O(N + E)$,其中 $E$ 是 dislikes 的长度。

  • 空间复杂度:$O(N + E)$。

统计信息

通过次数 提交次数 AC比率
9696 22280 43.5%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言
上一篇:
883-三维形体投影面积(Projection Area of 3D Shapes)
下一篇:
887-鸡蛋掉落(Super Egg Drop)
本文目录
本文目录