【leetcode】337 打家劫舍III(二叉树,递归,动态规划)

题目链接:https://leetcode-cn.com/problems/house-robber-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.

思路

该题的思路本质上是一个动态规划的过程,从根节点往下可以不断拆分成最优子问题,递归地解决;在回溯过程中汇总左右子树以及根节点的结果。在整个过程中不断更新最大收益。
该题只需要遍历一遍树即可,不需要额外空间。

核心的递归函数为robCore(TreeNode* root, int& prevSum)
prevSum是一个引用,用来返回以root为根节点的树中,不包含根节点的最大收益;
函数返回值是包含根节点的最大收益;

动态方程

某个树的最大收益 = max(包含根节点的最大收益,以及不包含根节点的最大收益);

不包含根节点的最大收益 = 左子树的最大收益 + 右子树最大收益

包含根节点的最大收益 = 不包含左子节点的左子树最大收益 + 根节点 + 不包含右子节点的最大收益

maxSum = max(maxSum,当前树的最大收益)

复杂度分析

  • 时间复杂度:O(n)。只遍历一遍所有节点
  • 空间复杂度:O(n)。递归栈的调用,如果树极度不平衡,空间复杂度为O(n);如果树平衡,为O(log N)。

代码

class Solution {
    int maxSum = 0;
public:
    int rob(TreeNode* root) {
        if(!root) return 0;
        int prevSum = 0;
        robCore(root, prevSum);
        return maxSum;
    }

private:
    // 返回值:包含该节点为的最大收益;
    // 引用返回prevSum:不包含末尾节点的最大收益
    int robCore(TreeNode* root, int& prevSum){
        if(!root){
            prevSum = 0;
            return 0;
        }
        if(!root->left && !root->right) {           // 无左右子树
            prevSum = 0;
            maxSum = max(maxSum, root->val);
            return root->val;
        }
        int prevLeft = 0, prevRight = 0;            // 左右子树不包含左右子节点部分的最大收益
        int left = robCore(root->left, prevLeft);   // 左子树包含左子节点部分的最大收益
        int right = robCore(root->right, prevRight);

        int sumWithRoot = root->val+ prevLeft+prevRight;        // 包含根节点值的最大收益
        prevSum = max(left,prevLeft) + max(right,prevRight);    // 不包含根节点的最大收益
        maxSum = max(maxSum, max(sumWithRoot,prevSum));         // 更新最大收益
        return sumWithRoot;
    }
};

【leetcode】337 打家劫舍III(二叉树,递归,动态规划)_第1张图片

你可能感兴趣的:(LeetCode)