337. House Robber III的C++解法(递归+dp)

本文解析LeetCode上House Robber III问题,探讨如何利用递归与动态规划解决二叉树中的抢劫问题,通过计算每个节点偷或不偷的最大收益,最终得出整棵树的最大抢劫金额。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:https://leetcode.com/problems/house-robber-iii/

一开始被描述中的例子误导了,觉得应该只能打劫间隔的一层,所以写了一个层次遍历,计算每一层的和再决定怎么打劫。后来发现是不对的,因为可以打劫左子树而不打劫右子树,如树[2,7,1,null,4,null,8]

对于二叉树中的某一个节点i,它也有偷与不偷这两个选项,若偷,则两个子节点不能偷;否则,两个子节点可以偷。与I、II不同的是,I、II中对当前的房屋i,偷与不偷仅需把其中的较大者保留下来进行,因为后续的结果均是建立在前者为最优解的基础上进行的,而且DP[i] = max{DP[i-1],DP[i-2]+A[i]}一定能保证不发生冲突;但是对于二叉树,当前节点i并不能那么方便的找到其子节点的子节点的最优解,因此并不能同I、II那样仅记录最优解。对于二叉树的节点而言,其最容易访问到的就是它的两个子节点。因此,可以建立一个大小为2的一维数组DP,其中DP[0]用来记录偷当前节点所能获利值,DP[1]用来记录不偷当前的值所能获利的值。使用递归的方法求解。

class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> res=helper(root);
        return max(res[0],res[1]);
        
    }
    vector<int> helper(TreeNode* root){
        vector<int> res={0,0};
        if (root==NULL) return res;
        //得到打劫或者不打劫左子树的结果
        vector<int> left=helper(root->left);
        //得到打劫或者不打劫右子树的结果
        vector<int> right=helper(root->right);
        //打劫根节点则不打劫左右子树
        res[0]=left[1]+right[1]+root->val;
        //否则计算左右子树可以打劫时的最大情况
        res[1]=max(left[0],left[1])+max(right[1],right[0]);
        return res;
        
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值