📜  二叉树的所有垂直级别的总和(1)

📅  最后修改于: 2023-12-03 14:49:01.494000             🧑  作者: Mango

二叉树的所有垂直级别的总和

二叉树是一种常见的数据结构,其中每个节点最多有两个子节点。在二叉树中,每个节点都有一个垂直级别,这是根节点到该节点的距离。在这个主题中,我们将讨论如何计算二叉树的所有垂直级别的总和。

方法一:使用哈希表

我们可以使用哈希表来存储每个节点的垂直级别和该级别的节点值总和。从根节点开始遍历二叉树,对于每个节点,我们将其值添加到其垂直级别的总和中,然后递归遍历其左子树和右子树。最后,我们将哈希表中所有级别的节点值总和相加,就得到了所有垂直级别的总和。

这里是使用Python实现的代码片段:

class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

def vertical_sum(root):
    if not root:
        return

    level_sums = {}
    queue = [(root, 0)]

    while queue:
        node, level = queue.pop(0)

        if level in level_sums:
            level_sums[level] += node.val
        else:
            level_sums[level] = node.val

        if node.left:
            queue.append((node.left, level - 1))
        if node.right:
            queue.append((node.right, level + 1))

    return sum(level_sums.values())

在这个代码片段中,我们定义了一个TreeNode类来表示二叉树的节点。vertical_sum函数使用哈希表和队列来计算所有垂直级别的总和。我们首先将根节点和其垂直级别0添加到队列中。然后,我们在队列中迭代,直到队列为空。对于每个弹出队列的节点,我们将其值添加到其垂直级别的节点值总和中。如果该级别在哈希表中不存在,则我们将其添加到哈希表中。然后,我们将该节点的左子节点添加到队列中,并将其垂直级别减1;将其右子节点添加到队列中,并将其垂直级别加1。最后,我们返回哈希表中所有级别的节点值总和的总和。

使用哈希表计算二叉树的所有垂直级别的总和的时间复杂度为O(n),其中n是二叉树中的节点数。这是因为我们必须遍历每个节点一次,并在哈希表中更新每个垂直级别的总和或将其添加到哈希表中。空间复杂度取决于哈希表和队列中存储的节点数,即O(n)。

方法二:使用双向链表

我们可以使用双向链表来存储二叉树中的所有节点,其中每个节点具有一个属性,该属性存储其垂直级别。我们可以使用递归来遍历树,每当我们遍历一个节点时,我们将其添加到双向链表中。最后,我们可以在链表中遍历节点并计算所有垂直级别的总和。

这里是使用Python实现的代码片段:

class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

class ListNode:
    def __init__(self, val):
        self.val = val
        self.prev = None
        self.next = None

def vertical_sum(root):
    if not root:
        return

    dummy = ListNode(0)
    curr = dummy

    def dfs(node, level):
        nonlocal curr
        if not node:
            return
        
        # 添加节点到双向链表
        new_node = ListNode(node.val)
        new_node.prev = curr
        curr.next = new_node
        curr = new_node

        dfs(node.left, level - 1)
        dfs(node.right, level + 1)

        curr = curr.prev

    dfs(root, 0)

    # 计算所有垂直级别的总和
    total = 0
    while dummy.next:
        total += dummy.next.val
        dummy.next = dummy.next.next
        if dummy.next:
            dummy.next.prev = dummy

    return total

在这个代码片段中,我们定义了一个TreeNode类来表示二叉树的节点,还定义了一个ListNode类来表示双向链表中的节点。vertical_sum函数使用双向链表和递归来计算所有垂直级别的总和。我们首先定义一个虚拟节点dummy和一个指向当前节点的指针curr。然后,我们使用dfs函数来递归遍历二叉树。对于每个节点,我们将其值添加到双向链表中,然后递归遍历其左子树和右子树。最后,我们将指针curr回退到其前一个节点,以便在返回上一级时正确更新链表。

一旦我们将所有节点添加到链表中,我们可以遍历链表并计算所有垂直级别的总和。我们使用一个虚拟节点dummy来遍历链表。我们从第一个实际节点开始,并将每个节点的值添加到总和中。然后,我们将虚拟节点dummy移到下一个节点,继续这个过程,直到链表为空为止。

使用双向链表计算二叉树的所有垂直级别的总和的时间复杂度为O(nlogn),其中n是二叉树中的节点数。这是因为链表中的节点数是O(nlogn),因为在每个递归层次上,我们最多只遍历二叉树中的一半节点。空间复杂度取决于链表中存储的节点数,即O(nlogn)。