[Leetcode] 337. House Robber III 解题报告
来源:互联网 发布:js在线压缩混淆 编辑:程序博客网 时间:2024/05/20 10:21
题目:
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.
Determine the maximum amount of money the thief can rob tonight without alerting the police.
Example 1:
3 / \ 2 3 \ \ 3 1Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
3 / \ 4 5 / \ \ 1 3 1Maximum amount of money the thief can rob = 4 + 5 = 9.
思路:
二叉树一般情况下用递归是最好的办法。分析本题目可知,要想获得最大值有两种选择:
1)抢劫根节点,那么此时就不能抢劫左右子树的根节点;
2)不抢劫根节点,那么此时就可以抢劫左右子树的根节点。
两种情况中取受益最大者即可。在实现中值得注意的是,在递归过程中有可能会引起重复计算。例如代码片段1中,我们在rob(root->left)的调用过程中会调用rob(root->left->left),而这个调用在rob(root)中也出现,导致大量重复计算。一种比较好的递归方式见代码片段2,我们采用“首递归”,并用传递引用的方式记录左右子树已经取得的最大值,可以完美地避免重复计算。(测试结果表明代码片段2的效率比代码片段1的效率高100倍左右)
代码:
1、低效递归:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: int rob(TreeNode* root) { if (!root) { return 0; } int rob_root = root->val; if (root->left) { rob_root += rob(root->left->left); rob_root += rob(root->left->right); } if (root->right) { rob_root += rob(root->right->left); rob_root += rob(root->right->right); } int not_rob_root = rob(root->left); not_rob_root += rob(root->right); return max(rob_root, not_rob_root); }};
2、高效递归:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: int rob(TreeNode* root) { int left = 0, right = 0; return rob(root, left, right); }private: int rob(TreeNode* root, int &left, int &right) { if(!root) { return 0; } int left_left = 0, left_right = 0, right_left = 0, right_right = 0; left = rob(root->left, left_left, left_right); // left_left and left_right will be updated during recursions right = rob(root->right, right_left, right_right); // right_left and right_right will be updated during recursions return max(root->val + left_left + left_right + right_left + right_right, left + right); }};
- [leetcode] 337. House Robber III 解题报告
- LeetCode 337. House Robber III 解题报告
- [Leetcode] 337. House Robber III 解题报告
- LeetCode-House Robber-解题报告
- 【LeetCode】House Robber 解题报告
- [leetcode] 337. House Robber III
- LeetCode#337. House Robber III
- LeetCode *** 337. House Robber III
- [leetcode]337. House Robber III
- LeetCode-337. House Robber III
- [leetcode]337. House Robber III
- LeetCode-337.House Robber III
- LeetCode 337. House Robber III
- Leetcode 337. House Robber III
- leetcode 337. House Robber III
- LeetCode - 337. House Robber III
- 【LeetCode】337. House Robber III
- 【leetcode】337. House Robber III
- Android 8.0 新特性及开发指南
- spring in action 笔记
- & | ^ ~ >> 和 <<运算符
- sklearn之决策树实战
- Android事件分发机制详解
- [Leetcode] 337. House Robber III 解题报告
- android 知识点收集
- LINUX 根目录下的 bin boot dev etc 这几个目录
- 排序算法三——插入排序
- 2017年校招全国统一模拟笔试(第四场)编程题集合--Python
- Java设计模式学习——结构型
- 1064. 朋友数
- 374. Guess Number Higher or Lower
- 核心类和类之间的关系