# LC 337. House Robber III ### [Problem link](https://leetcode.com/problems/house-robber-iii/) ###### tags: `leedcode` `python` `c++` `medium` `Binary Tree` `DP` The thief has found himself a new place for his thievery again. There is only one entrance to this area, called <code>root</code>. Besides the <code>root</code>, each house has one and only one parent house. After a tour, the smart thief realized that all houses in this place form a binary tree. It will automatically contact the police if **two directly-linked houses were broken into on the same night** . Given the <code>root</code> of the binary tree, return the maximum amount of money the thief can rob **without alerting the police** . **Example 1:** <img alt="" src="https://assets.leetcode.com/uploads/2021/03/10/rob1-tree.jpg" style="width: 277px; height: 293px;" /> ``` Input: root = [3,2,3,null,3,null,1] Output: 7 Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. ``` **Example 2:** <img alt="" src="https://assets.leetcode.com/uploads/2021/03/10/rob2-tree.jpg" style="width: 357px; height: 293px;" /> ``` Input: root = [3,4,5,1,3,null,1] Output: 9 Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9. ``` **Constraints:** - The number of nodes in the tree is in the range <code>[1, 10<sup>4</sup>]</code>. - <code>0 <= Node.val <= 10<sup>4</sup></code> ## Solution 1 - DP #### Python ```python= # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def rob(self, root: Optional[TreeNode]) -> int: # dp[0]: Maximum amount that can be obtained without stealing this node # dp[1]: Maximum amount that can be obtained by stealing this node def traversal(cur): if not cur: return [0, 0] left = traversal(cur.left) right = traversal(cur.right) dp = [max(left) + max(right), cur.val + left[0] + right[0]] return dp dp = traversal(root) return max(dp) ``` #### C++ ```cpp= class Solution { public: pair<int, int> traversal(TreeNode *node) { if (node == nullptr) { return make_pair(0, 0); } pair<int, int> l = traversal(node->left); pair<int, int> r = traversal(node->right); int noSteel = max(l.first, l.second) + max(r.first, r.second); int steel = l.first + node->val + r.first; return make_pair(noSteel, steel); } int rob(TreeNode* root) { pair<int, int> res = traversal(root); return max(res.first, res.second); } }; ``` >### Complexity >n = the number of nodes in the tree. >| | Time Complexity | Space Complexity | >| ----------- | --------------- | ---------------- | >| Solution 1 | O(n) | O(logn) | ## Note 樹型dp SC = O(high of the tree) = O(logn) dp[0]: 不偷這節點的最大值 = max(左節點不偷值, 左節點偷值) + max(右節點不偷值, 右節點偷值) dp[1]: 偷這節點的最大值 = 節點值 + 左節點不偷值 + 右節點不偷值 [代碼隨想錄](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0337.%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8DIII.md)