【问题标题】:Max sum root to leaf binary tree time complexity最大和根到叶二叉树时间复杂度
【发布时间】:2015-06-29 11:07:13
【问题描述】:
int ma = INT_MIN;
int parent[1000];

int findMaxPath(struct node * ptr) {
    if (ptr == NULL) return 0;
    if (ptr->left == NULL && ptr->right == NULL) {
        // means leaf node
        int sum = ptr->data;
        int temp = ptr->data;
        while (parent[temp] != -1) {
            sum = sum + parent[temp];
            temp = parent[temp];
        }
        if (sum > ma)
            ma = sum;
    }
    else{
        if (ptr->left != NULL)
            parent[ptr->left->data] = ptr->data;
        if (ptr->right != NULL)
            parent[ptr->right->data] = ptr->data;
        findMaxPath(ptr->left);
        findMaxPath(ptr->right);
    }
}

方法 - 一旦我识别出叶节点,我使用父数组回溯到根节点并对所有值求和,如果这个和值大于最大值,则更新最大值。 我不确定这段代码的时间复杂度你能帮我看看这段代码的时间复杂度吗?

【问题讨论】:

  • 这有点棘手,很大程度上取决于树的结构。对于具有单叶的单链树 - 它是O(n)。对于完美的完整树,它是O(nlogn),对于每个右子树的高度正好为 1 的树,它是 O(n^2)
  • @amit 你能解释一下吗?对于树遍历它是 O(n) 但我对如何思考 while 循环部分感到困惑

标签: c++ algorithm recursion tree binary-tree


【解决方案1】:

时间复杂度根据树的结构变化很大。

  • 对于平衡树,从根到叶的每条路径最多为 O(logn),并且叶数不超过n(显然),所以 O(nlogn)
  • 对于具有单叶的单链树 - 它是 O(n),因为您最多只能执行一次。
  • 对于每个右子树的高度正好为 1 的树,它是 O(n^2),因为您对正在增加的路径长度求和:1 + 2 + ... + n/2,它是算术级数之和的O(n^2)
算法的

最坏情况O(n^2),因为叶子不能超过n,并且每个深度不超过n - 这给出了@的上限987654333@,从示例中我们看到这个界限很紧。

算法的

平均情况O(nlogn),因为tree's average height is logarithmic

具有O(n) 时间和O(h) 空间的改进解决方案可以是DFS,其中存储和计算局部部分和,当遇到“更好”的解决方案时,只需编辑获得“更好”解决方案所需的指针" 解决方案。

【讨论】:

    【解决方案2】:

    在平衡树中,复杂度为 O(N*log(N)),因为所有节点中有一半是叶子,并且遍历回根需要 log(N)。如果树不平衡,您的速度可能会降低到 O(N2)。

    您可以通过将总和存储在遇到的每个节点中来修复您的方法,在这种情况下,时间复杂度将是 O(n),因为您永远不会重新计算您计算过一次的根到节点的总和.

    另一种实现线性的方法是从根运行BFSDFS,并计算每个顶点的总和。 DFS实现很简单:

    int max_sum(node *n, int partial) {
        if (n == NULL) {
            return partial;
        }
        int my_sum = partial + n->value;
        return max(max_sum(n->left, my_sum), max_sum(n->right, my_sum));
    }
    
    // Running the code:
    int maxSumInTree = max_sum(root, 0);
    

    【讨论】:

    • 为什么在 DFS 可以做 BFS 时(平均内存较少),在 BFS 中,您应该记住前面,以及到达每个节点的总和,(编辑:几乎是您接近的第一个解决方案) .
    • @amit 你是对的,因为我们在探索了一个顶点的所有子树之后不需要部分求和,DFS 也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 2014-02-05
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多