package
0.0.0-20241220224003-b7cf03a90b2b
Repository: https://github.com/szhou12/leetcode-go.git
Documentation: pkg.go.dev
# README
337. House Robber III
Solution idea
树形DP
-
使用一个长度为2的数组,记录当前节点偷与不偷所得到的的最大金钱。所以本题dp数组就是一个长度为2的数组!
-
Define DP: for any node, DP[0] = 记录不偷该节点所得到的的最大金钱; DP[1] = 录偷该节点所得到的的最大金钱。
-
Base Case: 在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回
-
Recurrence:
- 通过递归左节点,得到左节点偷与不偷的金钱。
- 通过递归右节点,得到右节点偷与不偷的金钱。
- 当前层:
- 如果是偷当前节点,那么左右孩子就不能偷,偷家总价值 = 左孩子不偷+右孩子不偷+当前层偷家的价值
- 如果不偷当前节点,那么左右孩子可以偷可以不偷,至于到底偷不偷一定是选一个最大的, 偷家总价值 = max(左孩子不偷, 左孩子偷) + max(右孩子不偷, 右孩子偷)
- 当前层状态 = [偷家总价值case 2, 偷家总价值case 1]
-
整体机制:后序遍历+DP. 即,先拿到左、右孩子有什么,当前层再做点什么,就可以返回了
Time complexity = $O(n)$
个人经验教训
我一开始错误地理解了偷家机制:我以为层与层之间不挨着偷家就行。但题目意思是说不能偷直接相连的两个节点,所以,即使是挨着的两层,也有可能下一层的节点与上一层的节点没有直接相连。(e.g. 下一层最左子树的节点,上一层最右子树的节点: [2,1,3,null,4])
因为错误理解,我的解法用了层序遍历+DP: 层序遍历求出每一层的偷家价值总和, 再用DP. 然而,思路一开始就不对