The thief has found himself a new place for his thievery again. There is only one entrance to this area, called root.
Besides the root, 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 root of the binary tree, return the maximum amount of money the thief can rob without alerting the police.
Input: root = [3,2,3,null,3,null,1]
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Input: root = [3,4,5,1,3,null,1]
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
The problem is an extension of the House Robber problem. Here, the houses are in the form of a binary tree, and the rule is the same: we cannot rob two directly-linked houses. A straightforward way to solve this problem is to use DFS and recursion to consider all possible combinations of robbing/not robbing a node and calculate the maximum amount.
The basic idea is:
To optimize the above approach, we implement memoization. The recursive approach recalculates the same values multiple times. Instead, we can store the results for each subtree for a node, which saves computation time.
We use a HashMap to store the result for each node so we don't compute the value of a node more than once.
Rather than relying solely on memoization, we can optimize further by using a pair of values returned for each node:
This approach allows us to eliminate the use of an external hashmap by encompassing all information in a succinct recursive return.
h is the height of the tree, due to recursion.