问题描述:不能偷相邻房屋
线性
- 如果打算偷当前房屋i,上一个可以偷的房屋至少是i-2
- 如果偷了上一个房屋, 则当前房屋不能偷
- dp数组含义: dp[i] 表示 偷盗第i个房屋时,能够偷取的最大值
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
环形
- 可以将圆环剪断,剪成线性; 和198打家劫舍的区别在于,头尾不能都偷
- 那就一定不能偷尾计算一次; 一定不能偷头计算一次,最后取这两次计算结果的最大值
树形
这个是最难的,动规+树形dp
- 分析题义,如果偷了父节点,一定不能偷孩子结点; 如果偷了孩子结点,一定不能偷父节点
- 这里要区分一下,一定不能偷和如果偷(偷/不偷都可以)
- 递归函数参数: 树节点
- 递归函数返回:[如果偷父节点的总值, 如果偷孩子结点总值] (返回两个元素)
- 递归边界: if not root: return[]
- dp定义: dp[0]: 如果偷父节点(当前传入参数结点)得到的最大值; dp[1]:如果偷了子节点的最大值
// 后序递归遍历 dp() return List[int]]
left = dp(root.left) // left为一个数组,left的定义和dp定义一致
right = dp(root.right)
steal_child = max(left) + max(right)
steal_father = root.val + left[1] + right[1]
return [steal_father, steal_child]