(接上一题)在上次打劫完一条街道之后和一圈房屋之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子组成的区域比较奇怪,聪明的窃贼考察地形之后,发现这次的地形是一颗二叉树。与前两次偷窃相似的是每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且当相邻的两个房子同一天被打劫时,该系统会自动报警。
算一算,如果今晚去打劫,你最多可以得到多少钱,当然在不触动报警装置的情况下。
样例
3
/ \
2 3
\ \
3 1
窃贼最多能偷窃的金钱数是 3 + 3 + 1 = 7.
3
/ \
4 5
/ \ \
1 3 1
窃贼最多能偷窃的金钱数是 4 + 5 = 9.
思路:对于每个节点需要考虑两种情况,分别是根节点加进返回值和不把根节点加进去两种。是根节点加进去就不能把两个子节点的值加进去,反之可以,对每个点这样递归考虑就能得到最终结果,我写了两种思路,第一种TLE大数据集超时,第二种顺利通过。
1 /** 2 * Definition of TreeNode: 3 * class TreeNode { 4 * public: 5 * int val; 6 * TreeNode *left, *right; 7 * TreeNode(int val) { 8 * this->val = val; 9 * this->left = this->right = NULL; 10 * } 11 * } 12 */
写法1:分别考虑把子节点加进去和不加进去两种情况,重复操作太多(重复计算了不少节点,分别作为子节点和孙节点),TLE
1 class Solution { 2 public: 3 /** 4 * @param root: The root of binary tree. 5 * @return: The maximum amount of money you can rob tonight 6 */ 7 int houseRobber3(TreeNode * root) { 8 write your code here 9 if(root==nullptr) return 0; 10 int without_root = houseRobber3(root->left) + houseRobber3(root->right);//不计root,去左右子节点之和 11 int with_root = root->val;//计入root,分别跳过子节点,直接加孙节点 12 if(root->left){ 13 with_root+=houseRobber3(root->left->left); 14 with_root+=houseRobber3(root->left->right); 15 } 16 if(root->right){ 17 with_root+=houseRobber3(root->right->left); 18 with_root+=houseRobber3(root->right->right); 19 } 20 return max(with_root,without_root);//取较大值返回,表示以当前为根节点的和最大值 21 } 22 };
写法2:自底向上后序遍历postOrder,返回两个值,分别表示当前根节点值可计入和不计入的最大和
1 class Info{//自定义了一个数据结构,返回两个值 2 public: 3 int with_root;//可计入根节点时最大值 4 int without_root;//不可计入时最大值 5 Info(int w,int wo):with_root(w),without_root(wo){}; 6 }; 7 8 class Solution { 9 public: 10 /** 11 * @param root: The root of binary tree. 12 * @return: The maximum amount of money you can rob tonight 13 */ 14 int houseRobber3(TreeNode * root) { 15 return postOrder(root).with_root; 16 } 17 18 Info postOrder(TreeNode * root){//后序遍历,自底向上 19 if(root==nullptr) return Info(0,0); 20 Info L = postOrder(root->left); 21 Info R = postOrder(root->right); 22 int with_root = root->val+L.without_root+R.without_root; 23 int without_root = L.with_root+R.with_root; 24 return Info(max(with_root,without_root),without_root);//这里的max很重要,with_root可以计入root也可以不计入,反正取最大值 25 } 26 };