最大总和根到叶二叉树时间复杂度

时间:2015-06-29 11:07:14

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

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);
    }
}

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

2 个答案:

答案 0 :(得分:2)

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

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

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

算法的

平均大小写O(nlogn),因为tree's average height is logarithmic

O(n)时间和O(h)空间的改进解决方案可以是DFS,其中存储和计算本地部分和,并且当遇到"更好"解决方案,只需编辑指针即可获得更好的"溶液

答案 1 :(得分:1)

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

您可以通过在所遇到的每个节点中存储总和来修复您的方法,在这种情况下,时间复杂度将是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);