Leetcode|树形排列|337. 打家劫舍 III

文章目录

    • 0 打家劫舍系列
    • 1 动态规划(记忆化递归)
    • 2 动态规划(一维树形状态转移)

Leetcode|树形排列|337. 打家劫舍 III_第1张图片

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];
    }
};

Leetcode|树形排列|337. 打家劫舍 III_第2张图片

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]);
    }
};

Leetcode|树形排列|337. 打家劫舍 III_第3张图片

你可能感兴趣的:(Leetcode动态规划专题)