leetcode 337. House Robber III | 337. 打家劫舍 III(树形dp;什么情况下dp需要强制包含当前元素?)

题目

https://leetcode.com/problems/house-robber-iii/
在这里插入图片描述


思考:什么情况下 dp 需要强制包含当前元素?

dp 过程中,需要包含当前元素 的例子:

dp 过程中,不需要包含当前元素 的例子:

当问题类似于 前缀和问题、背包问题 的时候,也就是 对 dp 数组的访问是按照索引进行随机访问 的情况下,需要在每一个状态上包含元素本身信息,所以这种情况下 通常强制包含当前元素

而当问题类似于 打家劫舍 问题的时候,结果与被遍历序列的前后顺序有关,对 dp 数组的访问只涉及到 i-1, i-2 等这些有限个数的相邻下标(假设当前元素下标为 i),不需要对前面的 dp 数组进行随机访问,这时不需要存储每一个状态下的元素本身信息,通常不用强制包含当前元素


题解

参考了:https://leetcode.com/problems/house-robber-iii/discuss/79330/Step-by-step-tackling-of-the-problem 的开头,有了点思路,后面自己写的。

可以看作是一个树形 dp 问题,也可以参考:左神算法:找到二叉树中的最大搜索二叉子树(树形dp套路,Java版)

class Solution {
    public int rob(TreeNode root) {
        if (root == null) return 0;

        rob(root.left);
        rob(root.right);

        int l, r, ll, lr, rl, rr;
        l = r = ll = lr = rl = rr = 0;

        if (root.left != null) {
            l = root.left.val;
            if (root.left.left != null) {
                ll = root.left.left.val;
            }
            if (root.left.right != null) {
                lr = root.left.right.val;
            }
        }
        if (root.right != null) {
            r = root.right.val;
            if (root.right.left != null) {
                rl = root.right.left.val;
            }
            if (root.right.right != null) {
                rr = root.right.right.val;
            }
        }

        // root.val 存储【偷或不偷】当前元素时的最大值
        root.val = Math.max(root.val + ll + lr + rl + rr, l + r);
        return root.val;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值