LeetCode刷题笔记 10.26 二叉树染色

为什么刷这道题

首先这道题是我前两天笔试的时候一道题的简化情况,也就是这道题k = 1的情况。

开始的时候我是怎么想的

刚开始我想的是,二叉树层序遍历,然后计算隔层的相加和,然后用例只过了30%,后来想想,我这个想法是很不对的,因为不一定一层的节点需要选完,有可能只选一部分,所以这样的话只能过一些正好符合这个思路的用例。

力扣原题

之后我便在力扣上找到了原题,如下:
https://leetcode-cn.com/problems/er-cha-shu-ran-se-UGC/
题目描述:
小扣有一个根结点为 root 的二叉树模型,初始所有结点均为白色,可以用蓝色染料给模型结点染色,模型的每个结点有一个 val 价值。小扣出于美观考虑,希望最后二叉树上每个蓝色相连部分的结点个数不能超过 k 个,求所有染成蓝色的结点价值总和最大是多少?

思路

这道题的话呢,它就是一个二叉树+dp的解法
首先,动态规划的解题框架如下:
1.定义状态转移方程
2.给定转移方程初始值
3.写代码递归实现转移方程

动态规划的话,有自底向上和自顶向下两种,这道题是自底向上的,保存子节点的状态并计算当前是否染色的状态。

1.状态转移方程

定义一维数组dp[k + 1]
dp[i] 表示每个节点的状态,i表示染了几个节点,i = 0表示没染色,i > 0表示染色

若当前节点为root,dp逻辑如下:
root不染色,那么只要返回 dp[0],其值为左、右子树染色或不染色的最大值之和
root染色,那么就分左子树染色 j 个,右子树染色 i - 1 - j 个时,加上 root.val 的和。
注意:j 需要从 0 取到 i - 1,也就是包含 l[0] 和 r[0]。因为 l[0] 也包含左子树染了j个节点的情况,因为左子树的下一层子节点可能染了j个节点。

dp[i] = Math.max(dp[i], root.val + l[j] + r[i - 1 - j]);
2.初始值

初始值为 叶子节点下的空节点,所以 直接返回都为 0 的 new int[k + 1];

3.代码实现
class Solution {
   
  public int maxValue(TreeNode root, int k) {
   
  

你可能感兴趣的:(leetcode,动态规划,算法)