leetcode刷题笔记337题 打家劫舍 III
问题描述:
在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。
计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
示例 1:
输入: [3,2,3,null,3,null,1]
3
/
2 3
3 1输出: 7
解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.
示例 2:输入: [3,4,5,1,3,null,1]
3
/
4 5
/
1 3 1输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.
//树状DP问题 认为每个节点存在两种状态 即选择与未选择
/**
* Definition for a binary tree node.
* class TreeNode(var _value: Int) {
* var value: Int = _value
* var left: TreeNode = null
* var right: TreeNode = null
* }
*/
object Solution {
def rob(root: TreeNode): Int = {
val ans = dfs(root)
return math.max(ans(0), ans(1))
}
def dfs(root: TreeNode): Array[Int] = {
val ans = Array.fill(2)(0)
if (root == null) return ans
val x = dfs(root.left)
val y = dfs(root.right)
ans(0) = math.max(x(0), x(1)) + math.max(y(0), y(1))
ans(1) = x(0) + y(0) + root.value
return ans
}
}
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func rob(root *TreeNode) int {
ans := dfs(root)
return max(ans[0], ans[1])
}
func dfs(root *TreeNode) []int {
if (root == nil) {return []int{0, 0}}
x := dfs(root.Left)
y := dfs(root.Right)
return []int{max(x[0], x[1])+max(y[0], y[1]), x[0]+y[0]+root.Val}
}
func max(a, b int) int {
if a > b {
return a
} else {
return b
}
}