打家劫舍3-中等
题目:
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root
。
除了 root
之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。
给定二叉树的 root
。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。
解题思路
第一,不能简单地隔层计算,然后求最大值。因为如果大值出现在首尾,则行不通。
那么,考虑动态规划。
对于每个节点,都有两种选择:1)选中,那么其值就是当前节点值和左右子节点的不被选择的值,之和。
2)不选中,那么其值就是左节点中或选中或不选中的最大值,加上右子树选中或者不选中的最大值,之和。
// date 2024/03/01
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
var dfs func(root *TreeNode) [2]int
dfs = func(root *TreeNode) [2]int {
if root == nil {
return [2]int{0, 0}
}
l, r := dfs(root.Left), dfs(root.Right)
// select root
v1 := root.Val + l[1] + r[1]
// no root
v2 := max(l[0], l[1]) + max(r[0], r[1])
return [2]int{v1, v2}
}
res := dfs(root)
return max(res[0], res[1])
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
最后更新于