题目描述:
给定一颗二叉树,每个节点上有一定的价值。小偷希望在不触发警报的情况下,偷取二叉树中的节点,获取最大的总价值。
解题思路:
我们可以使用递归来解决这个问题。对于每个节点,我们有两种选择:偷取该节点或不偷取该节点。为了获得最大的总价值,我们需要考虑这两种情况,并选择其中较大的那个。
具体步骤如下:
-
定义一个递归函数
pair<int, int> robSubtree(TreeNode* root)
,该函数接受一个二叉树节点作为参数,并返回一个包含两个整数的pair。第一个整数表示不偷取当前节点时的最大总价值,第二个整数表示偷取当前节点时的最大总价值。 -
在递归函数中,首先判断当前节点是否为空,如果为空则返回
{0, 0}
,表示不偷取和偷取当前节点的总价值都为0。 -
对于非空节点,递归计算其左子树和右子树的结果,分别表示不偷取和偷取左子树以及不偷取和偷取右子树时的最大总价值。
-
计算偷取当前节点的最大总价值
robRoot
,它等于当前节点的价值加上不偷取左子树和右子树时的最大总价值,即robRoot = root->val + left.second + right.second
。 -
计算不偷取当前节点的最大总价值
notRobRoot
,它等于不偷取左子树和右子树中的节点时的最大总价值,即notRobRoot = max(left.first, left.second) + max(right.first, right.second)
。 -
返回一个包含
robRoot
和notRobRoot
的pair,表示在当前节点处的最大总价值。 -
在主函数
int rob(TreeNode* root)
中,调用robSubtree
函数计算整棵树的最大总价值,并返回较大者即可。
以下是相应的C++代码实现:
class Solution {
public:
pair<int, int> robSubtree(TreeNode* root) {
if (!root) {
return {0, 0};
}
pair<int, int> left = robSubtree(root->left);
pair<int, int> right = robSubtree(root->right);
int robRoot = root->val + left.first + right.first;
int notRobRoot = max(left.first, left.second) + max(right.first, right.second);
return {notRobRoot, robRoot};
}
int rob(TreeNode* root) {
pair<int, int> result = robSubtree(root);
return max(result.first, result.second);
}
};