LeetCode——二叉树染色

题目描述

小扣有一个根结点为 root 的二叉树模型,初始所有结点均为白色,可以用蓝色染料给模型结点染色,模型的每个结点有一个 val 价值。小扣出于美观考虑,希望最后二叉树上每个蓝色相连部分的结点个数不能超过 k 个,求所有染成蓝色的结点价值总和最大是多少?
示例 1:
输入:root = [5,2,3,4], k = 2
输出:1
image.png
解释:结点 5、3、4 染成蓝色,获得最大的价值 5+3+4=12

示例 2:
输入:root = [4,1,3,9,null,null,2], k = 2
输出:16
image.png
解释:结点 4、3、9 染成蓝色,获得最大的价值 4+3+9=16

提示:
1 <= k <= 10
1 <= val <= 10000
1 <= 结点数量 <= 10000

题解

  • 根据K判断当前节点可不可以染。

  • 可以染的情况下还需判断染或不染。

  • 使用Map记录每个节点不染情况下,以其为根节点的子树的最大收益。避免超时

    /**
    * Definition for a binary tree node.
    * public class TreeNode {
    *     int val;
    *     TreeNode left;
    *     TreeNode right;
    *     TreeNode(int x) { val = x; }
    * }
    */
    class Solution {
      public int maxValue(TreeNode root, int k) {
      // map用于记录当前根节点不染时,子树的最大收益
      HashMap<TreeNode,Integer>map=new HashMap<>();
      return solve(root,k,k,map);
      }
      public int solve(TreeNode root,int k,int curK,HashMap<TreeNode,Integer>map) {
      if(root==null) {
          return 0;
      }
      // 连续染色的节点数达到阈值,当前节点不染
      if(curK==0) {
          if(map.containsKey(root)) {
              return map.get(root);
          }
          int value=solve(root.left,k,k,map)+solve(root.right,k,k,map);
          map.put(root, value);
          return value;
      }
      int value1=0;
      // 当前节点染时,左右连续被染的节点数不能超过阈值
      for(int left=0;left<=curK-1;++left) {
          int value=root.val+solve(root.left,k,left,map)+solve(root.right,k,curK-1-left,map);
          if(value1<value) {
              value1=value;
          }
      }
    
      // 连续被染节点数没达到阈值时,当前节点可以不染
      int value2=0;
      if(map.containsKey(root)) {
          value2= map.get(root);
      }else {
          int valueLeft=solve(root.left,k,k,map);
          int valueRight=solve(root.right,k,k,map);
          value2=valueLeft+valueRight;
          map.put(root, value2);
      }
      return value1>value2?value1:value2;
      }
    }
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务