题目:
给你一个数组 pairs ,其中 pairs[i] = [xi, yi] ,并且满足:
- pairs 中没有重复元素
- xi < yi
令 ways 为满足下面条件的有根树的方案数:
- 树所包含的所有节点值都在 pairs 中。
- 一个数对 [xi, yi] 出现在 pairs 中 当且仅当 xi 是 yi 的祖先或者 yi 是 xi 的祖先。
注意:构造出来的树不一定是二叉树。
两棵树被视为不同的方案当存在至少一个节点在两棵树中有不同的父节点。
请你返回:
- 如果 ways == 0 ,返回 0 。
- 如果 ways == 1 ,返回 1 。
- 如果 ways > 1 ,返回 2 。
一棵 有根树 指的是只有一个根节点的树,所有边都是从根往外的方向。
我们称从根到一个节点路径上的任意一个节点(除去节点本身)都是该节点的 祖先 。根节点没有祖先。
思路:
解答:
class Solution:
def checkWays(self, pairs: List[List[int]]) -> int:
#degree[x]:pairs 中包含节点 x 的数对的数目,等于len(adj[x])
#adj[x]:节点 x 的祖先和后代的节点集合
adj=defaultdict(set)
for x,y in pairs:
adj[x].add(y)
adj[y].add(x)
n=len(adj)
#print(adj)
#检测是否存在根节点,即是否存在一个点x,使得len(neighbors)==n
flag=False
for node,neighbors in adj.items():
if len(neighbors)==n-1:
flag=True
root=node
break
#不存在根节点,不能构成一颗合法的树
if not flag:
return 0
ans = 1
#遍历每个节点,判断其父节点是否满足要求
for node, neighbors in adj.items():
if node == root:
continue
currDegree = len(neighbors)
parent = -1
parentDegree = float('inf')
# 根据 degree 的大小找到 node 的父节点 parent
for neighbor in neighbors:
if currDegree <= len(adj[neighbor]) < parentDegree:
parent = neighbor
parentDegree = len(adj[neighbor])
# 检测 neighbours 是否为 adj[parent] 的子集
if parent == -1 or any(neighbor != parent and neighbor not in adj[parent] for neighbor in neighbors):
return 0
if parentDegree == currDegree:
ans = 2
return ans