📜  有向二叉树中严格递增和递减路径的计数(1)

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

有向二叉树中严格递增和递减路径的计数

在有向二叉树中,树中的每个节点最多只有两个子节点,且每个节点有一个指向其左子节点和另一个指向其右子节点的有向边。

严格递增路径是从根节点开始到叶子节点结束的路径,其路径上所有节点值严格递增。递减路径则相反,路径上所有节点值严格递减。

给定一颗有向二叉树,本题要求计算其中所有严格递增路径和递减路径的数量。

思路

对于二叉树中的每个节点,我们可以分别计算以该节点作为路径终点的递增路径和递减路径个数。假设当前节点为 node,则其递增路径和递减路径个数分别为 inc[node]dec[node]

对于一个节点,其递增路径数等于其左孩子 left_node 和右孩子 right_node 的递增路径数之和,且需要在其中加上一条有向边从该节点到其左孩子或右孩子。

即:inc[node] = inc[left_node] + inc[right_node] + (node -> left_node) + (node -> right_node)

同理,对于递减路径,我们需要加上一条有向边从 left_noderight_node 指向该节点:dec[node] = dec[left_node] + dec[right_node] + (left_node -> node) + (right_node -> node)

最终统计整颗二叉树的递增路径和递减路径即可。

代码实现
class Solution:
    def countIncDecPaths(self, root: TreeNode) -> int:
        if not root:    # 空树
            return 0
        self.res = 0
        self.inc, self.dec = {}, {}
        self.dfs(root)
        for node in self.inc:
            self.res += self.inc[node] + self.dec[node] - 2   # 求和,注意存在重复
        return self.res

    def dfs(self, node):
        if not node:
            return 0, 0
        # 计算以当前节点作为递增路径和递减路径终点的路径数
        left_inc, left_dec = self.dfs(node.left)
        right_inc, right_dec = self.dfs(node.right)
        # 计算包括当前节点的递增路径和递减路径数量
        inc = left_inc + right_inc
        if node.left:
            inc += left_inc + (node.val < node.left.val)
        if node.right:
            inc += right_inc + (node.val < node.right.val)
        dec = left_dec + right_dec
        if node.left:
            dec += left_dec + (node.val > node.left.val)
        if node.right:
            dec += right_dec + (node.val > node.right.val)
        # 记录当前节点的递增路径和递减路径数量
        self.inc[node] = inc
        self.dec[node] = dec
        return inc, dec

以上代码中,我们使用 dfs 函数来计算以每个节点为路径终点的递增路径和递减路径个数,并将其记录在 incdec 中。最终我们再遍历 incdec 中的所有节点,分别将它们的递增路径数和递减路径数相加,再将结果相加即可。

总结

本题考察了以二叉树为数据结构的基本操作,包括遍历、递归和动态规划。解决本题需要明确每个节点的计算方法,同时注意存在重复计算的情况。