题解 | 打家劫舍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);
    }
};

复杂度分析

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

相关推荐

01-22 10:28
已编辑
中国矿业大学 Java
点赞 评论 收藏
分享
2025-12-26 09:25
门头沟学院 Java
如果能回到求职第一天,我真想狠狠敲醒当初那个天真又莽撞的自己:停下!别再拿着那份潦草又单薄的简历到处海投了,这根本不是争取机会,纯粹是浪费时间、消耗心气!你以为随便扒个网上的模板,凑个苍穹外卖的项目,就敢底气十足地冲美团、字节这些大厂?太可笑了!那份简历里,项目经历寥寥几笔,技术栈写得杂乱无章,既没深挖过项目里的技术难点,也没梳理过业务逻辑,甚至连自己做的模块能解决什么问题都说不清,这样的简历投出去,只会石沉大海,全是无效投递!你要记住,简历不是随便堆砌的文字,是你的敲门砖,更是你能力的缩影。花点心思沉下来,把每一个项目都挖透&nbsp;——&nbsp;梳理清楚项目的整体架构、你负责的核心模块,琢磨透用到的技术原理,设想好面试官会问到的各种场景,把你解决过的问题、优化过的流程、沉淀的经验都写进去,让简历有内容、有亮点、有说服力。更重要的是,别只盯着简历包装,背后的硬实力才是根本。你要吃透项目里的每一项技术,搞懂底层逻辑,而不是只记个皮毛就沾沾自喜。求职从来不是碰运气,你敷衍对待简历,敷衍打磨自己,就只能换来一次次的简历挂、面试挂。别再盲目海投、急于求成,慢下来,把简历打磨好,把能力夯实透,你的每一份用心,都会在求职路上给你回报。那些看似走得快的人,不过是提前做好了准备,而你,本该也可以。
pdd评选年度最幸运...:当初总觉得错过一个offer天就塌了,现在回头看,路其实很多条。
重来一次,你会对开始求职...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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