题目链接:https://leetcode.com/problems/redundant-connection-ii/description/
这次变成了有向图。给定一颗有N个节点的树,树中有N条边,要求删除有向图中的一条边,使删除边后的图是一棵树。
考虑一棵树中,多了一条边后,会有两种情况:
1、图中有环
2、图中某个节点有两个父节点。
其实还有一种情况是图中既有环,又有某个节点有两个父节点,比如[ [2,1], [3,1], [4,2], [1,4] ]。在这种情况下可以按图中某个节点有两个父节点来处理。对于这两种情况,处理方式如下:
1、按照输入顺序删除环中的最后一条边
2、对于这两条边,删除其中一条后,如果有环,则结果为另外一条边;若删除后没有环,则结果为该条边
代码如下:
class Solution(object):
def findFather(self,root,paths):
'''
寻找根节点
'''
while paths[root]!=root:
root=self.findFather(paths[root],paths)#这段代码写的真好,寻找根节点,并压缩路径
return root
def isCycle(self,first,second,paths):
'''
判断是否构成环
'''
first_father=self.findFather(first,paths)#寻找根节点
second_father=self.findFather(second,paths)#寻找根节点
return (True if first_father==second_father else False)
def findRedundantDirectedConnection(self, edges):
"""
:type edges: List[List[int]]
:rtype: List[int]
"""
probilities=None
length_edges=len(edges)
paths=range(length_edges+1)
for [first,second] in edges:
if paths[second]!=second:#如果某个节点有两个父节点
probilities=[ [paths[second],second],[first,second] ]
break
paths[second]=first
if probilities:#如果某个节点有两个父节点
paths=range(length_edges+1)
for edge in edges:
[first,second]=edge
if edge == probilities[1]:#删除边probilities[1]
continue
elif self.isCycle(first,second,paths):#如果删除probilities[1]图中还存在环
return probilities[0]#那么应删除probilities[0]
paths[second]=first
return probilities[1]#如果删除probilities[1]后没有环,那么probilities[1]即为结果
#如果没有一个节点有两个父节点,则检查存在环的情况
paths=range(length_edges+1)
for [first,second] in edges:
if self.isCycle(first,second,paths):
return [first,second]
paths[second]=first
其实这道题我只考虑到了第二种情况,并解决了;第一种情况也想到了,但是没有怎么解决。主要原因是想通过一种方式统一的处理这两种情况,最后没有想到,看的答案。以后一定要先解决问题,不用管什么方法,再想怎么去简化吧!