LintCode 535. 打劫房屋 III

(接上一题)在上次打劫完一条街道之后和一圈房屋之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子组成的区域比较奇怪,聪明的窃贼考察地形之后,发现这次的地形是一颗二叉树。与前两次偷窃相似的是每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且当相邻的两个房子同一天被打劫时,该系统会自动报警。

算一算,如果今晚去打劫,你最多可以得到多少钱,当然在不触动报警装置的情况下。

样例
      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 };

 

转载于:https://www.cnblogs.com/J1ac/p/8849857.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值