337. 打家劫舍 III

本文探讨了树形结构上的动态规划问题,即在树状结构中如何选择节点进行盗窃以获得最大收益,同时确保相邻节点不会同时被选中。通过定义节点被盗和未被盗两种状态,利用递归后序遍历的方法,自底向上地计算每个节点的最优解,最终得到树根节点的最大收益。

题目
在这里插入图片描述
树上DP。
对于树的一个节点开始,它的子树可以盗取的最大金额由它的两个状态组成:

  • 该点被盗,记为f(i)
  • 该点不被盗,记为g(i)

f f f g g g 由其左右节点的状态决定:
f ( i ) = n o d e . v a l + g ( l ) + g ( r ) f(i)=node.val+g(l)+g(r) f(i)=node.val+g(l)+g(r)
g ( i ) = m a x g(i)=max g(i)=max { f ( l ) , g ( l ) } + m a x \lbrace f(l),g(l)\rbrace+max {f(l),g(l)}+max { f ( r ) , g ( r ) } \lbrace f(r),g(r)\rbrace {f(r),g(r)}

最后 f ( r o o t ) f(root) f(root) g ( r o o t ) g(root) g(root)的最大值就是最后答案。

由递推式可以看出,应该是从底向上就是递推,左右根得出结论,因此采用后序遍历方法,逐步推出结果。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    Map<TreeNode,Integer> f=new HashMap<TreeNode,Integer>();
    Map<TreeNode,Integer> g=new HashMap<TreeNode,Integer>();

    public int rob(TreeNode root) {
        dfs(root);
        return Math.max(f.getOrDefault(root,0),g.getOrDefault(root,0));
    }

    private void dfs(TreeNode node){
        if(node==null) return;
        dfs(node.left);
        dfs(node.right);
        f.put(node,node.val+g.getOrDefault(node.left,0)+g.getOrDefault(node.right,0));
        g.put(node,Math.max(f.getOrDefault(node.left,0),g.getOrDefault(node.left,0))+Math.max(f.getOrDefault(node.right,0),g.getOrDefault(node.right,0)));
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值