用动态规划的思想解决这道题。
对于每一个节点,只有两种可能,偷或者不偷。
对于一颗以root为根节点的二叉树,定义rob表示偷root节点能从这棵二叉树偷到的最大金额。定义notrob表示不偷root节点能从这棵二叉树偷到的最大金额。
递推公式分析如下:
rob = root->val + (不偷左孩子能从左子树偷到的最大金额)+(不偷右孩子能从右子树偷到的最大金额)
notrob = (从左子树能偷到的最大金额)+(从右子树能偷到的最大金额)
求root的值,需要先求左子树和右子树的情况,因此需要用二叉树的后序遍历,先递归的处理左子树和右子树。
代码:
/*** 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) {int rob_root; //偷根节点能偷到的最大金额int notrob_root;//不偷根节点能偷到的最大金额postRob(root,rob_root,notrob_root);return max(rob_root,notrob_root);}void postRob(TreeNode* root,int &rob,int ¬rob){if(root == nullptr){rob = 0;notrob = 0;return;}int leftrob=0; //偷左孩子能从左子树偷到的最大金额int leftnotrob=0;//不偷左孩子能从左子树偷到的最大金额postRob(root->left,leftrob,leftnotrob);int rightrob=0; //偷右孩子能从右子树偷到的最大金额int rightnotrob=0;//不偷右孩子能从右子树偷到的最大金额postRob(root->right,rightrob,rightnotrob);rob = root->val + leftnotrob + rightnotrob;notrob = max(leftrob,leftnotrob) + max(rightrob,rightnotrob);}
};