[LeetCode]337. House Robber III

回溯,递归法

Posted by JinFei on March 19, 2021

题目描述

The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the “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 forms a binary tree”. It will automatically contact the police if two directly-linked houses were broken into on the same night.

Determine the maximum amount of money the thief can rob tonight without alerting the police.

Example1:

Input: [3,4,5,1,3,null,1]
3
/ \
4 5
/ \ \
1 3 1
Output: 9 Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.

解题思路

  • 参考 博客
  • 这种问题是很典型的递归问题,可以利用回溯法来做,
  • 因为当前的计算需要依赖之前的结果,那么对于某一个节点,如果其左子节点存在,通过递归调用函数,算出不包含左子节点返回的值,同理,如果右子节点存在,算出不包含右子节点返回的值,
  • 那么此节点的最大值可能有两种情况,一种是该节点值加上不包含左子节点和右子节点的返回值之和,另一种是左右子节点返回值之和不包含当期节点值,取两者的较大值返回即可,
  • 但是这种方法无法通过 OJ,超时了,所以必须优化这种方法,这种方法重复计算了很多地方,比如要完成一个节点的计算,就得一直找左右子节点计算,可以把已经算过的节点用 HashMap 保存起来,以后递归调用的时候,现在 HashMap 里找,如果存在直接返回,如果不存在,等计算出来后,保存到 HashMap 中再返回,这样方便以后再调用
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int rob(TreeNode* root) {
        int res = 0;
        unordered_map<TreeNode*, int> mmap;
        return dfs(root, mmap);
    }
    int dfs(TreeNode* root, unordered_map<TreeNode*, int>& mmap){
        if(root == NULL){
            return 0;
        }
        if(mmap.count(root) != 0){      // 如果之前已经存过值了
            return mmap[root];
        }
        int res = 0;
        if(root -> left){ // 对于当前节点,中间隔一个节点root -> left,root -> right,防止出现 NULL -> left的情况
            res += dfs(root -> left -> left, mmap) + dfs(root -> left -> right, mmap);
        }
        if(root -> right){
            res += dfs(root -> right -> left, mmap) + dfs(root -> right -> right, mmap);
        }
        // 最后的结果应该是(算上本次的节点) 上面隔的节点的 + 根节点, 和(不算本次的节点)
        res = max(res + root -> val, dfs(root -> left, mmap) + dfs(root -> right, mmap));
        mmap[root] = res;
        return res;
    }
};

如果不打表的话,会报TLE超时

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    // unordered_map<TreeNode*, int> mmap;
    int rob(TreeNode* root) {
        return fun_helper(root);
    }
    int fun_helper(TreeNode* root){
        if(root == nullptr){
            return 0;
        }
        // if(mmap.count(root) != 0){
        //    return mmap[root];
        // }
        int res = 0;
        if(root -> left){
            res += fun_helper(root -> left -> left) + fun_helper(root -> left -> right);
        }
        if(root -> right){
            res += fun_helper(root -> right -> right) + fun_helper(root -> right -> left);
        }
        res = max(res + root -> val, fun_helper(root -> left) + fun_helper(root -> right));
        // mmap[root] = res;
        return res;
    }
};