Leetcode Problem 337: House Robber III

一个二叉树,每个节点有一个正整数数值。存在某个节点子集,使得其中节点对应的数值的和最大,前提:如果某节点在此子集中,其直接父亲节点和直接儿子节点不得出现在此子集中。求这个最大值。

动态规划。

最大值一定是在下面两种情况之一:根节点在子集中,但根节点的直接儿子节点不在子集中;根节点不在子集中。即最大值要么是根节点的所有孙子节点(儿子节点的儿子节点,最多4个)的最大值之和加上根节点的值,要么是两个儿子节点的最大值之和。显然计算子树最大值的方法是可以递归的,递归的终结状态是空树(最大值为0)。

请注意,上述方法中,某个节点为根节点的子树的最大值要求多次,所以要使用填表法来避免重复运算。

  • 空间复杂度:O(n) n为节点个数
  • 时间复杂度:O(n)
/**
 * 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 {
private:
    map table;
    
public:
    int rob(TreeNode* root) {
        if (root == NULL) {
            return 0;
        }
        
        if (table.find(root) != table.end()) {
            return table[root];
        }
        
        int a = root->val;
        
        if (root->left != NULL) {
            a += rob(root->left->left);
            a += rob(root->left->right);
        }
        if (root->right != NULL) {
            a += rob(root->right->left);
            a += rob(root->right->right);
        }
        
        int b = rob(root->left) + rob(root->right);
        
        int max = (a > b) ? a : b;
        table.insert(pair (root, max));
        return max;
    }
};

你可能感兴趣的:(Leetcode Problem 337: House Robber III)