• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Niro Einteson
文可提笔安天下 武可上马定乾坤
博客园    首页    新随笔    联系   管理    订阅  订阅

337. 打家劫舍 III

337. 打家劫舍 III

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

示例 1:

输入: [3,2,3,null,3,null,1]

3
/ \
2 3
\ \
3 1

输出: 7
解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.
示例 2:

输入: [3,4,5,1,3,null,1]

  3
/ \
4 5
/ \ \
1 3 1

输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.

 

未优化

 1 class Solution {
 2 public:
 3     int rob(TreeNode* root) {
 4         if(root==NULL) return 0;
 5         if(root->left==NULL&&root->right==NULL) return root->val;
 6         else {
 7             //这样一句话写下来,可能有空的,无法进行继续,比如 root->left=null, 则root->left->left报错
 8             // return max(rob(root->left)+rob(root->right), root->val+rob(root->left->left)+rob(root->left->right)+rob(root->right->left)+rob(root->right->right));
 9             int ls=0,ls1=0,ls2=0,lr=0,lr1=0,lr2=0;
10             if(root->left!=NULL){
11                 if(root->left->left!=NULL){
12                     ls1=rob(root->left->left);
13                 }
14                 if(root->left->right!=NULL){
15                     ls2=rob(root->left->right);
16                 }
17                 ls=rob(root->left);
18             }
19             if(root->right!=NULL){
20                 if(root->right->left!=NULL){
21                     lr1=rob(root->right->left);
22                 }
23                 if(root->right->right){
24                     lr2=rob(root->right->right);
25                 }
26                 lr=rob(root->right);
27             }
28             // rob  函数的返回值 代表 从当前根 往下走 所选房间的 最大值 ; 即 max( 左子树的返回值+右子树的返回值,根的值+左子树的左子树的返回值+左子树的右子树的返回值+右子树的左子树的返回值+右子树的右子树的返回值);
29             return max(ls+lr,root->val+ls1+ls2 + lr1+lr2 );
30         }
31     }
32 };

 

记忆化存储-优化

 1 class Solution {
 2 public:
 3     map<TreeNode*,int> mp;
 4     int rob(TreeNode* root) {
 5         if(root==NULL) return 0;
 6         if(mp[root]) return mp[root];
 7        // if(root->left==NULL&&root->right==NULL) return root->val;不需要,写了也对
 8         else {
 9             //抢左右子树的子树
10            int lss= root->left==NULL?0:rob(root->left->left)+rob(root->left->right);
11            int lrs=root->right==NULL?0:rob(root->right->left)+rob(root->right->right);
12            //抢左右子树
13            int sum=rob(root->left)+rob(root->right);
14            //算出最大值
15            int val=max(sum,root->val+lss+lrs);
16            //记忆化存储
17            mp[root]=val;
18            return val;
19 
20         }
21     }
22 };

 

 1 class Solution {
 2 public:
 3     //[0] 表示不抢 root 的话,得到的最大钱数
 4     //[1] 表示抢 root 的话,得到的最大钱数 
 5     vector<int> dfs(TreeNode* root){
 6         if(root==NULL) return {0,0};
 7         vector<int>left=dfs(root->left);
 8         vector<int>right=dfs(root->right);
 9         int sum=root->val+left[0]+right[0];//抢,则左右子树不能抢
10         int Nsum=max(left[0],left[1])+max(right[0],right[1]);//不抢,下家可抢可不抢
11         return {Nsum,sum};
12     }
13     int rob(TreeNode* root) {
14         vector<int> res=dfs(root);
15         return max(res[0], res[1]);
16     }
17 };

 

posted @ 2020-03-17 21:16  Nirogo  阅读(157)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3