0886. 可能的二分法
题目地址(886. 可能的二分法)
https://leetcode.cn/problems/possible-bipartition
题目描述
前置知识
图的遍历
DFS
公司
暂无
思路
这是一个图的问题。解决这种问题一般是要遍历图才行的,这也是图的套路。 那么遍历的话,你要有一个合适的数据结构。 比较常见的图存储方式是邻接矩阵和邻接表。
而我们这里为了操作方便(代码量),直接使用邻接矩阵。由于是互相不喜欢,不存在一个喜欢另一个,另一个不喜欢一个的情况,因此这是无向图。而无向图邻接矩阵实际上是会浪费空间,具体看我下方画的图。
而题目给我们的二维矩阵并不是现成的邻接矩阵形式,因此我们需要自己生成。
我们用 1 表示互相不喜欢(dislike each other)。
同时可以用 hashmap 或者数组存储 N 个人的分组情况, 业界关于这种算法一般叫染色法,因此我们命名为 colors,其实对应的本题叫 groups 更合适。
我们用:
0 表示没有分组
1 表示分组 1
-1 表示分组 2
之所以用 0,1,-1,而不是 0,1,2 是因为我们会在不能分配某一组的时候尝试分另外一组,这个时候有其中一组转变为另外一组就可以直接乘以-1,而 0,1,2 这种就稍微麻烦一点而已。
具体算法:
遍历每一个人,尝试给他们进行分组,比如默认分配组 1.
然后遍历这个人讨厌的人,尝试给他们分另外一组,如果不可以分配另外一组,则返回 False
那问题的关键在于如何判断“不可以分配另外一组”呢?
实际上,我们已经用 colors 记录了分组信息,对于每一个人如果分组确定了,我们就更新 colors,那么对于一个人如果分配了一个组,并且他讨厌的人也被分组之后,分配的组和它只能是一组,那么“就是不可以分配另外一组”。
代码表示就是:
最后有两个问题需要注意:
if colors[i] == 0 and not self.dfs(graph, colors, i, 1, N)
可以改为if colors[i] == 0 and not self.dfs(graph, colors, i, -1, N):
么?
可以的。这不影响答案。假设改成 -1 后的染色分布情况已知,那么其染色分布情况等价于使用 1 的情况的反色(将颜色 1 替换为颜色-1,颜色-1 替换为颜色 1)而已。对是否可以二分图没有任何影响。
接上:那有没有可能使用颜色 1 推出矛盾,而使用颜色 -1 则推出成立呢?
没有可能。一次 dfs 处理的是一个子图。多次开启 dfs 不会相交,自然不存在这个问题。不信你可以将代码改成如下测试一下:
为什么不需要 visited 数组来防止遍历过程中环的产生?
实际上,我们的 colors 数组就起到了 visited 的作用。如果 colors[i] == 0,因为着 visited[i] 为 False,否则为 True
关键点
二分图
染色法
图的建立和遍历
colors 数组
代码
复杂度分析
令 V 为点的个数。
最坏的情况下是稠密图,边的数量为点的数量的平方个。此时 graph 的空间为 $O(V^2)$, colors 空间为$O(V)$。由于需要遍历所有的点和边,因此时间复杂度为 $V+E$,由前面的分析最坏 E 是 $V^2$,因此空间复杂度为 $O(V^2)$
时间复杂度:$O(V^2)$
空间复杂度:$O(V^2)$
相关问题
更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
最后更新于