题解 | 打家劫舍III

alt

题干解析

去除背景后: 题设定义一颗二叉树,允许我们任意选取不连续的节点,要求返回所有选取方式中所选取节点值之和最大的值。

算法思路

递归分解问题:

  • 针对空树根,我们无从选择。
  • 针对单节点树根,我们有两种选择:选择该根节点/不选择该根节点。
  • 针对一般树根,依旧两种选择:选择该根节点/不选择该根节点。

我们想要让我们的选择总和尽可能大。考虑普通的树根:

  • 如果我们选择根节点,则两个子树需在根节点均不能选的情况下得到最大选择。
  • 如果我们不选择根节点,则子树的节点选择并无过多限制,得到最大选择了即可。

子树的最大选择也可以依照树根类推,只不过同样考虑两种情况,选择子树根节点/不选择子树根节点。

以此作为递归元问题即可解决该问题。

实现代码

class L337 {
    pair<int, int> dfs(TreeNode *node) {
        if (!node) return {0, 0}; // 空树
        auto [leftR, leftNR] = dfs(node->left); // 左子树的两种最大选择情况
        auto [rightR, rightNR] = dfs(node->right); // 右子树
        int R = leftNR + rightNR + node->val; // 选择根节点
        int NR = max(leftR, leftNR) + max(rightR, rightNR); // 不选择根节点
        return {R, NR};
    }
public:
    int rob(TreeNode* root) {
        auto [rootR, rootNR] = dfs(root);
        return max(rootR, rootNR);
    }
};

复杂度分析

  • 时间复杂度:每个节点递归访问一次,时间复杂度为
  • 空间复杂度:最坏情况下,二叉树是一个链表,递归空间消耗占主体,空间复杂度最坏为
全部评论

相关推荐

WhythZ:这个人老是在各种帖子底下出现,复制粘贴他的那套一样的话术,看着就烦
实习怎么做才有更好的产出
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务