📌  相关文章
📜  计算在二叉树中具有恰好 K 个不同节点的根到叶路径(1)

📅  最后修改于: 2023-12-03 15:41:38.501000             🧑  作者: Mango

在二叉树中计算具有恰好 K 个不同节点的根到叶路径

在二叉树中,从根节点到叶子节点的路径称为根到叶路径。对于给定的整数 K,我们需要计算在二叉树中有多少条根到叶路径,其中路径上恰好包含 K 个不同的节点。

例如,对于下面的二叉树和 K=3,我们可以计算出具有恰好 3 个不同节点的根到叶路径有两条,即 1->2->4 和 1->3->6。

       1
      / \
     2   3
    /   / \
   4   5   6
解法

我们可以使用递归来遍历二叉树并计算路径。对于每个节点,我们可以将其作为路径的起点,并沿着子树向下遍历,计算路径上的不同节点数。如果路径的节点数等于 K 并且当前节点为叶子节点,那么我们可以将该路径计数器加 1。

代码如下:

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

def count_paths(root: TreeNode, k: int) -> int:

    def count_paths_helper(node: TreeNode, path: set) -> int:
        if not node:
            return 0

        path.add(node.val)
        count = 0

        if not node.left and not node.right: # 叶子节点
            if len(path) == k:
                count = 1
        else:
            count += count_paths_helper(node.left, path)
            count += count_paths_helper(node.right, path)

        path.remove(node.val)

        return count

    return count_paths_helper(root, set())

我们通过一个辅助函数 count_paths_helper 递归地遍历二叉树。我们使用一个集合来记录当前路径上的节点,并将每个节点的值添加到集合中。然后,我们继续递归遍历子树,直到到达叶子节点。如果当前路径包含 k 个不同的节点,那么我们就将计数器加 1。最后,我们从集合中删除当前节点,并返回计数器的值。

时间复杂度

我们需要遍历整个二叉树一次,并且对于每个叶子节点,需要执行一次常数时间的集合操作。因此,总的时间复杂度为 $O(n)$,其中 $n$ 是节点的数量。

空间复杂度

我们需要使用额外的空间来存储每个路径上的节点。由于路径最长为 $n$,因此我们需要 $O(n)$ 的空间复杂度。

总结

这道题目可以通过递归遍历二叉树来解决。关键在于如何记录当前路径上的不同节点,并在到达叶子节点时判断是否满足条件。

参考资料: