题目描述:LeetCode-二叉树染色
本题使用动态规划+深度优先搜索解法
首先需要有一个大致的解题方向:本题是针对二叉树的最优化(求最大值最小值问题),对于最优化问题,一般想到采用动态规划解法。但是有了大致方向,具体的步骤——设计状态转移方程以及方程的初始值的确定依然是难点。这记录一下我参考学习 官网的题解后的解法
对于二叉树中的每个节点,都有染色或不染色两种选择。对于每个节点node
我们构建一维动规表dp[k+1]
,表长度为k+1
,其中dp[0]
存储不染色情况下以节点node
为根的子树的最大价值;当i>0
时,dp[i]
存储包括节点node
在内连续i
个节点染色的情况下的子树最大价值。
计算dp
中的值,需要当前节点node
的左右子树的动规结果,分别称为l
和r
。当节点node
不染色,dp[0]
为l
和r
的最大值之和;当节点node
染色,有dp[1~k]
共k
种情况,每个dp[i]
考虑左子树染色j
个(0<=j<=i-1)
的情况,同时右子树染色i-1-j
,取其中的最大值,即dp[i]=max(node.val+l[j]+r[i-j-1])
。
因此dp
方程为:
//对于节点为空情况
dp[i]=0 // i>=0 && i<=k
//对于节点不为空的情况
dp[0]=max(l)+max(r)
dp[i]=max(node.val+l[j]+r[i-j-1]) //i>0 && i<=k, j>=0 && j<i
确定好每个节点的动规表dp
,我们用深度优先方法进入二叉树最底层节点,再自底向上并返回每个节点的dp
,直到根节点。
题解代码:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x)