![在这里插入图片描述](https://img-blog.csdnimg.cn/20210329212804228.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NMX1dvcmxk,size_16,color_FFFFFF,t_70)
0 打家劫舍系列
《Leetcode|线性排列|198. 打家劫舍》
《Leetcode|环形排列|213. 打家劫舍 II》
《Leetcode|树形排列|337. 打家劫舍 III》
1 动态规划(记忆化递归)
class Solution {
private:
unordered_map<TreeNode*, int> memo;
public:
int rob(TreeNode* root) {
if (!root) return 0;
if (memo.count(root)) return memo[root];
// 1.不偷
int notRob = rob(root->left) + rob(root->right);
// 2.偷
int isRob = root->val + (root->left ? (rob(root->left->left) + rob(root->left->right)) : 0)
+ (root->right ? (rob(root->right->left) + rob(root->right->right)) : 0);
memo[root] = max(notRob, isRob);
return memo[root];
}
};
2 动态规划(一维树形状态转移)
适合构建通用树形DP思维
class Solution {
public:
vector<int> robTree(TreeNode* root) {
if (!root) return {0, 0};
// 后序遍历
auto left = robTree(root->left); // 左子树的偷 + 不偷
auto right = robTree(root->right); // 右子树的偷 + 不偷
// 1.不偷
int notRob = max(left[0], left[1]) + max(right[0], right[1]);
// 2.偷
int isRob = root->val + left[0] + right[0];
return {notRob, isRob};
}
int rob(TreeNode* root) {
// 不偷-dp[0]; 偷-dp[1]
auto dp = robTree(root); // dp树问题终究是递归问题,返回值可以是dp数组
return max(dp[0], dp[1]);
}
};