leetcode-886可能的二分法

给定一组 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
dislikes[i].length == 2
1 <= dislikes[i][j] <= N
dislikes[i][0] < dislikes[i][1]
对于 dislikes[i] == dislikes[j] 不存在 i != j

因为要分到2组
意思就是有一些人不呢能分到一个组里面,然后构建二部图,把不能分到一组的人连线,连线的人不能同样的颜色。然后用bfs或DFS对图进行遍历,染色。如果正好都能染色,则可以成功分组。否则不能成功分组。

在这里插入图片描述

from typing import List


class Solution:
    def possibleBipartition(self, N: int, dislikes: List[List[int]]) -> bool:
        def bfs(graph, colors, dislike):
            # 邻接表广度优先遍历
            graph = [[] for _ in range(N + 1)]
            colors = [0 for _ in range(N + 1)]
            for dis in dislikes:
                graph[dis[0] - 1].append(dis[1] - 1)
                graph[dis[1] - 1].append(dis[0] - 1)

            que = []  # 队列,广度优先遍历使用的, 染色,入队
            for i in range(N):
                if colors[i] != 0:  # 当前节点染色过了,不需要染色,推出下一个结点
                    continue
                colors[i] = 1  # 当前节点染色,结点入队
                que.append(i)

                while len(que) != 0:  # 广度优先遍历
                    cur = que.pop(0)
                    for num in graph[cur]:
                        if colors[num] == colors[cur]:  # 邻居颜色相等
                            return False
                        if colors[num] != 0:  # 已经染过色了
                            continue
                        colors[num] = -colors[cur]
                        que.append(num)
            return True





        # 邻接表深度优先遍历
        # 构建图
        graph = [[] for _ in range(N+1)]
        # 构建每个节点的颜色数组,共N个结点
        colors_ = [0 for _ in range(N+1)]
        # 构建不喜欢矩阵,然后染色,如果能正确染色,则能True分组,否则False
        for dis in dislikes:
            graph[dis[0]].append(dis[1])
            graph[dis[1]].append(dis[0])

        def dfs(pos, color):
            colors_[pos] = color  # 当前节点染色
            for i in graph[pos]:  # 深度遍历判断 我的第一个邻居不能跟我一个颜色
                if colors_[i] == color:
                    return False
                if colors_[i] == 0 and not dfs(i, -color):
                    # 邻居没染色,并且染相反的颜色失败。意思就是跟我一个颜色
                    return False
            return True  # 当前节点染色成功

        # 遍历所有节点  因为题目中的结点从开始计数
        for i in range(1, N+1):  # 从第一个结点开始,判断没有染色,并且染色。dfs染色。
            if colors_[i] == 0 and not dfs(i, 1):
                return False
        return True







































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值