337. House Robber III

本文介绍了如何运用回溯法优化解决LeetCode上的337题——HouseRobberIII,即在不触发警报的情况下,盗贼能从二叉树中的房子中盗取的最大金额。虽然最初的回溯法解法会超时,但通过保存已计算节点的结果到哈希映射中,避免重复计算,可以提高效率。文章详细展示了优化后的C++代码实现。
摘要由CSDN通过智能技术生成

337. House Robber III

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.

 

Example 1:

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:

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 [1, 104].
  • 0 <= Node.val <= 104

解题思路:

可以利用回溯法来做,因为当前的计算需要依赖之前的结果,那么对于某一个节点,如果其左子节点存在,通过递归调用函数,算出不包含左子节点返回的值,同理,如果右子节点存在,算出不包含右子节点返回的值,那么此节点的最大值可能有两种情况,一种是该节点值加上不包含左子节点和右子节点的返回值之和,另一种是左右子节点返回值之和不包含当期节点值,取两者的较大值返回即可,但是这种方法无法通过 OJ,超时了,所以必须优化这种方法,这种方法重复计算了很多地方,比如要完成一个节点的计算,就得一直找左右子节点计算,可以把已经算过的节点用 HashMap 保存起来,以后递归调用的时候,现在 HashMap 里找,如果存在直接返回,如果不存在,等计算出来后,保存到 HashMap 中再返回,这样方便以后再调用,参见代码如下:

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

[LeetCode] 337. House Robber III 打家劫舍之三

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值