↓Skip to main content
  1. LeetCode/

LeetCode 337: House Robber III

·2 mins· ·
LeetCode Medium Dynamic-Programming Tree Depth-First-Search Binary-Tree
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2022-11-16

  • Submissions: Wrong Answer ×2 → Runtime Error ×2 → Accepted → Wrong Answer → Accepted ×2

Approach
#

Adjacent (parent-child) nodes cannot both be robbed. Each node returns two values (Tree Template 7):

  • rob: rob it, so children are skipped: val + left.skip + right.skip.
  • skip: skip it, so each child takes its better option: max(left) + max(right).

The answer is the larger of the root’s two values.

My Attempts
#

Attempt 1 robbed either all odd or all even levels, but the best choice may skip two levels: for [1, 2, 3, 8], robbing 8 and 3 gives 11, while the level approach got 9. Switching to recursion, one version returned nothing and one did invalid arithmetic on tuples (TypeError).

Solution
#

class Solution:
    def rob(self, root: Optional[TreeNode]) -> int:
        def dfs(node):
            if not node:
                return 0, 0                          # (搶它, 不搶它)
            lr, ls = dfs(node.left)
            rr, rs = dfs(node.right)
            return node.val + ls + rs, max(lr, ls) + max(rr, rs)
        return max(dfs(root))

Complexity
#

Time O(n), space O(h).

Mistakes to Avoid
#

  • Summing odd and even levels is not enough: the best choice may skip two levels in a row.

Interview Explanation
#

This is tree DP: each node returns its best totals when robbed and when skipped; robbing excludes the children, skipping lets each child choose its better option, and the root takes the larger. Time O(n).

Related

LeetCode 1448: Count Good Nodes in Binary Tree
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 1448 note: pass the path maximum down during DFS; a node is good when its value is at least that maximum
LeetCode 199: Binary Tree Right Side View
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 199 note: in a level-order traversal, each level’s rightmost node is what you see from the right
LeetCode 230: Kth Smallest Element in a BST
·1 min
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 230 note: a BST’s in-order traversal is ascending, so stop an iterative in-order walk at the k-th node
LeetCode 98: Validate Binary Search Tree
·2 mins
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 98 note: every node has a valid range (low, high); going left the upper bound becomes the node and going right the lower bound does; comparing parent and child is not enough
LeetCode 606: Construct String from Binary Tree
·1 min
LeetCode Medium String Tree Depth-First-Search Binary-Tree
LeetCode 606 note: output in pre-order, keeping an empty () when only the left subtree is missing, and omitting the right parentheses when it is empty
LeetCode 235: Lowest Common Ancestor of a Binary Search Tree
·2 mins
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 235 note: go left when both p and q are smaller, right when both are larger; otherwise (split, or one is the node itself) this node is the LCA