简体   繁体   English

获取N-ary树中较大祖先的数量

[英]Get the count of larger ancestors in N-ary tree

We have a tree with nodes numbered from 1 to N . 我们有一棵树,节点编号从1N It is given to us in the format of 3 arrays vals , edge1 , edge2 . 它以3个数组valsedge1edge2的格式提供给我们。 vals[i] has the value of node i + 1 . vals [i]具有节点i + 1的值。 And there is an edge from edge1[i] to edge2[i]. 从edge1 [i]到edge2 [i]有一条边。 The tree is rooted at 1. 树根植于1。

I want to calculate the number of ancestors that are larger than the current nodes value for every node in the tree and return them in the an array. 我想计算树中每个节点的大于当前节点值的祖先数,并将它们返回到数组中。

This is a working algorithm: 这是一个有效的算法:

def get_larger_ancestors(vals, edge1, edge2):
    tree = defaultdict(set)
    for u, v in zip(B, C):
        tree[u].add(v)
        tree[v].add(u)

    parents = {1:None}
    que = deque([1])
    seen = set()
    while que:
        current = que.popleft()
        seen.add(current)
        for node in tree[current]:
            if node not in seen:
                parents[node] = current
                que.append(node)

    result = [None] * len(A)
    for val in tree:
        count = 0
        target = A[val - 1]
        p = val
        while p:
            p = parents[p]
            if p is None: break
            if A[p - 1] > target:
                count += 1
        result[val - 1] = count


    return result

The time complexity of the above algorithm is quadratic in the worst case. 在最坏的情况下,上述算法的时间复杂度是二次的。 It has to run on around 10^6 nodes. 它必须在大约10 ^ 6个节点上运行。

How do I improve the time complexity? 如何提高时间复杂度?

For some graphs complexity of your algorithm is O(n) , eg tree from m nodes there m-1 are direct children of the root node. 对于某些图,您的算法的复杂度为O(n) ,例如来自m节点的树,其中m-1是根节点的直接子节点。 For some graphs it is O(n^2) , eg tree with one long leg. 对于某些图形,它是O(n^2) ,例如具有一条长腿的树。 Then it is 1+2+3+..+(n-1) . 然后它是1+2+3+..+(n-1)

What you can do is instead of iterating through all parents store them in a balanced tree and find position of every next child in logarithmic time instead of your current linear time. 您可以做的不是迭代所有父母将它们存储在平衡树中,而是以对数时间而不是当前线性时间找到每个下一个孩子的位置。 With this change your worst time would decrease from quadratic to O(n*log(n)) . 通过此更改,您的最差时间将从二次减少到O(n*log(n)) See here for a logs summation formula. 请参阅此处了解日志求和公式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM