打家劫舍 III
树形 DP 入门题:每个节点维护“偷 / 不偷”两种状态,自底向上合并左右子树。
#resource / algorithm
#type / snippet
#status / growing
#source / leetcode
#algo / dp
打家劫舍 III
题目链接:https://leetcode.cn/problems/house-robber-iii/
为什么是树形 DP
每个节点都面临两种状态:
- 偷当前节点
- 不偷当前节点
并且选择会影响左右孩子是否能偷。
状态设计
对每个节点返回一个长度为 2 的数组:
res[0]:不偷当前节点时的最大收益res[1]:偷当前节点时的最大收益
转移
- 不偷当前节点:左右子树都可以偷也可以不偷,取各自最大值
- 偷当前节点:左右孩子都不能偷
JavaScript
var rob = function(root) {
function dfs(node) {
if (!node) return [0, 0];
const left = dfs(node.left);
const right = dfs(node.right);
const notRob = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
const robNode = node.val + left[0] + right[0];
return [notRob, robNode];
}
const res = dfs(root);
return Math.max(res[0], res[1]);
};