2018-06-01 Is Family?

You have a list of family relationships between father and son. Every element on this list has two elements. The first is the father's name, the second is a son’s name. All names in the family are unique. Check if the family tree is correct. There are no strangers in the family tree. All connections in the family are natural.

Input: list of lists. Every element has two strings. List has at least one element

Output: bool. Is family tree correct.


如题所示,给定一个包含n个二元列表的列表,每一个子列表包含一个“父子关系”,需要判断给定列表是否构成一个合理的家族。(既不存在陌生人,也不存在关系冲突——如互为父子),返回布尔值。


分析:

两种情况应该分别处理,存在陌生人则返回False,存在关系冲突也返回False,否则遍历完成后返回True。


陌生人情形:

我们考虑进行第一次遍历——首先将第一个列表内的父子加入一个新列表,对于剩下的列表,当新的父子对之一存在于新列表中时,才将新的父子对加入新列表并去重,最差时间复杂度为O(n^2),因此可以在while循环中加入时钟判断,当超过阈值时返回False


父子矛盾情形:

考虑将新列表维护为一个字典,即——父亲的value总是比儿子的小1,当加入新父子对时,若二者均存在于列表中,并发现value值存在矛盾,则返回False。


逻辑通过情形:

在时钟阈值内,当原列表长度计数为0时,返回True。


def is_family(tree):
    length = len(tree)
    if length == 1:
        print('Only one pair!')
        return True
    clock = length**2 # 时钟
    check_dict = {tree[0][0]:1,tree[0][1]:2} # 判断字典
    length -= 1 # 剩余未判断过的父子对
    while True:
        for pairs in tree:
            clock -= 1 # 进行了一次判断
            if pairs[0] not in check_dict and pairs[1] not in check_dict: # 不能确定是否陌生人,先跳过
                pass
            elif pairs[0] in check_dict and pairs[1] in check_dict: # 若已存在于判断字典中,判断关系序列是否正确
                if check_dict[pairs[0]] != check_dict[pairs[1]] - 1 :
                    print('Wrong relationship')
                    return False
            elif pairs[0] in check_dict: # 若父亲已存在于字典中,将儿子添加进入
                length -= 1
                check_dict[pairs[1]] = check_dict[pairs[0]] + 1
            elif pairs[1] in check_dict: # 若儿子已存在于字典中,判断是否有两个父亲的冲突
                for keys in check_dict:
                    if check_dict[keys] == check_dict[pairs[1]] - 1:
                        print("Who is your daddy?")
                        return False
                length -= 1
                check_dict[pairs[0]] = check_dict[pairs[1]] - 1 # 未冲突,将父亲添加入字典
            if length == 0: # 当所有的父子对均被判断过
                print('Is Family')
                return True
            if clock == 0: # 当时钟超过阈值
                print('Stranger!')
                return False

上述就是我的思路,感觉在时间复杂度上可以优化,例如维护一个包含已判断过的父子对的列表中位置序号的列表,使用enumerate方法,理论上最差时间为sigma(n-1)*2 = n^2-n

希望读者有更优的解法可以赐教。

猜你喜欢

转载自blog.csdn.net/contr4l_/article/details/80543283
今日推荐