区间动态规划例题:最长同值路径问题(二叉树中的最大同值路径长度)
字数 893 2025-11-10 16:33:32

区间动态规划例题:最长同值路径问题(二叉树中的最大同值路径长度)

题目描述
给定一棵二叉树的根节点root,你需要找到这棵树中最长的同值路径的长度。这条路径要求路径上的所有节点值相同,且路径可以不经过根节点。路径长度用路径上的边数表示。

例如,对于二叉树[5,4,5,1,1,null,5],最长的同值路径长度为2。

解题思路
虽然这是树结构问题,但可以使用类似区间DP的思想,采用后序遍历(左右根)的方式处理:

  1. 定义状态:dp[node]表示以node为起点的向下同值路径的最大长度
  2. 状态转移:比较node与左右子节点的值,决定是否延长同值路径
  3. 全局记录:在遍历过程中记录跨越当前节点的最长同值路径

详细解题步骤

步骤1:状态定义

  • 定义递归函数dfs(node),返回以node为起点的向下同值路径最大长度
  • 同时维护全局变量max_len记录整个树中的最大同值路径长度

步骤2:递归终止条件

  • 如果node为空,返回0(空节点没有路径)

步骤3:递归左右子树

left_len = dfs(node.left)   # 左子树的最大同值路径长度
right_len = dfs(node.right) # 右子树的最大同值路径长度

步骤4:计算当前节点的同值路径
分两种情况考虑:

  1. 与左子节点同值:如果node.left存在且node.val == node.left.val

    • 左路径长度 = left_len + 1
    • 否则左路径长度 = 0
  2. 与右子节点同值:如果node.right存在且node.val == node.right.val

    • 右路径长度 = right_len + 1
    • 否则右路径长度 = 0

步骤5:更新全局最大值

  • 当前节点作为"桥梁",连接左右同值路径:
    current_len = left_path + right_path
  • 更新max_len = max(max_len, current_len)

步骤6:返回以当前节点为起点的最大长度

  • 返回max(left_path, right_path)给父节点

完整算法示例

def longestUnivaluePath(root):
    max_len = 0
    
    def dfs(node):
        if not node:
            return 0
            
        left = dfs(node.left)    # 左子树结果
        right = dfs(node.right)  # 右子树结果
        
        # 计算当前节点的左右路径长度
        left_path = 0
        right_path = 0
        
        if node.left and node.left.val == node.val:
            left_path = left + 1
            
        if node.right and node.right.val == node.val:
            right_path = right + 1
        
        # 更新全局最大值(当前节点作为连接点)
        nonlocal max_len
        max_len = max(max_len, left_path + right_path)
        
        # 返回以当前节点为起点的最大长度
        return max(left_path, right_path)
    
    dfs(root)
    return max_len

复杂度分析

  • 时间复杂度:O(n),每个节点访问一次
  • 空间复杂度:O(h),递归栈深度,h为树的高度

这种解法将树形结构分解为子问题,体现了区间DP"分治+记忆"的核心思想。

区间动态规划例题:最长同值路径问题(二叉树中的最大同值路径长度) 题目描述 给定一棵二叉树的根节点root,你需要找到这棵树中最长的同值路径的长度。这条路径要求路径上的所有节点值相同,且路径可以不经过根节点。路径长度用路径上的边数表示。 例如,对于二叉树[ 5,4,5,1,1,null,5 ],最长的同值路径长度为2。 解题思路 虽然这是树结构问题,但可以使用类似区间DP的思想,采用后序遍历(左右根)的方式处理: 定义状态:dp[ node ]表示以node为起点的向下同值路径的最大长度 状态转移:比较node与左右子节点的值,决定是否延长同值路径 全局记录:在遍历过程中记录跨越当前节点的最长同值路径 详细解题步骤 步骤1:状态定义 定义递归函数dfs(node),返回以node为起点的向下同值路径最大长度 同时维护全局变量max_ len记录整个树中的最大同值路径长度 步骤2:递归终止条件 如果node为空,返回0(空节点没有路径) 步骤3:递归左右子树 步骤4:计算当前节点的同值路径 分两种情况考虑: 与左子节点同值:如果node.left存在且node.val == node.left.val 左路径长度 = left_ len + 1 否则左路径长度 = 0 与右子节点同值:如果node.right存在且node.val == node.right.val 右路径长度 = right_ len + 1 否则右路径长度 = 0 步骤5:更新全局最大值 当前节点作为"桥梁",连接左右同值路径: current_ len = left_ path + right_ path 更新max_ len = max(max_ len, current_ len) 步骤6:返回以当前节点为起点的最大长度 返回max(left_ path, right_ path)给父节点 完整算法示例 复杂度分析 时间复杂度:O(n),每个节点访问一次 空间复杂度:O(h),递归栈深度,h为树的高度 这种解法将树形结构分解为子问题,体现了区间DP"分治+记忆"的核心思想。