LeetCode 886. Possible Bipartition

LeetCode 886

第一个想法是,就直接去归类,使用两个集合,根据关系把这些点放入集合,看看是否能分类成功。

    def possibleBipartitionTimeout(self, N: int, dislikes: List[List[int]]) -> bool:
        if len(dislikes) <= 1: return True

        A = set()
        B = set()

        def canBipartition(dislikes, index, A, B) -> bool:
            if index >= len(dislikes): return True
            
            current = dislikes[index]
            if (current[0] in A and current[1] in A) or (current[0] in B and current[1] in B):
                return False
            
            if current[0] in A:
                B.add(current[1])
                return canBipartition(dislikes, index + 1, A, B)

            if current[1] in A:
                B.add(current[0])
                return canBipartition(dislikes, index + 1, A, B)

            if current[0] in B:
                A.add(current[1])
                return canBipartition(dislikes, index + 1, A, B)
            
            if current[1] in B:
                A.add(current[0])
                return canBipartition(dislikes, index + 1, A, B)

            Ac = A.copy()
            Bc = B.copy()
            Ac.add(current[0])
            Bc.add(current[1])
            if (canBipartition(dislikes, index + 1, Ac, Bc)):
                return True
            
            A.add(current[1])
            B.add(current[0])
            return canBipartition(dislikes, index+1, A, B)

提交之后发现效率太低,超时了。

转换思路,改用在图里面找loop的方式,A不喜欢B,B不喜欢C,C不喜欢D,D不喜欢E,E不喜欢A。如果分成两类的话,在A的这边就会造成一个内部的循环。只要存在类似的loop,那么就是False。通过DFS的方式可以走遍整个图。但是图可能是不连通的,所有需要根据每个节点来做一次dfs。

    def possibleBipartition(self, N: int, dislikes: List[List[int]]) -> bool:
        if len(dislikes) <= 1: return True
        graph = collections.defaultdict(list)
        hasLoop = False
        #-1表示还没有访问过
        distance = [-1] * (N+1)

        def dfs(start:int):
            nonlocal hasLoop
            if hasLoop: return
			
            for neighbor in graph[start]:
            	#如果在自己一侧引起循环,设置hasLoop为True
                if distance[neighbor] > 0 and (distance[neighbor] - distance[start]) % 2 == 0:
                    hasLoop = True
                    return
                elif distance[neighbor] == -1:
                    distance[neighbor] = distance[start] + 1
                    dfs(neighbor)

        for a, b in dislikes:
            graph[a].append(b)
            graph[b].append(a)

		#遍历每个点进行DFS
        for i in range(1, N):
            if hasLoop: return False
			
			#如果已经访问过,不需要重复访问
            if distance[i] == -1:
                distance[i] = 0
                dfs(i)

        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值