算法-动态规划-打家劫舍3

╰半夏微凉° 2023-03-06 05:03 78阅读 0赞

算法-动态规划-打家劫舍3

1 题目概述

1.1 题目出处

https://leetcode-cn.com/problems/house-robber-iii

1.2 题目描述

在这里插入图片描述

2 动态规划

2.1 思路

见代码注释。

2.2 代码

  1. /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */
  2. class Solution {
  3. public int rob(TreeNode root) {
  4. if(root == null){
  5. return 0;
  6. }
  7. // 需要分别考虑选本节点和不选本节点的两种情况
  8. // 选本节点时,最大金额取决于本节点金额加上不选左右子节点的最大金额
  9. // 而不选本节点时,最大金额计算就比较麻烦了,不一定选左右子节点就是最大金额
  10. // 所以这里必须要使用一个数组,分别记录选当前节点时的最大金额以及不选当前节点时的最大金额
  11. // 元素0代表选择本节点时的最大金额,元素1代表不选本节点时的最大金额
  12. int[] result = dfs(root);
  13. return Math.max(result[0], result[1]);
  14. }
  15. private int[] dfs(TreeNode root){
  16. // 元素0代表选择本节点时的最大金额,元素1代表不选本节点时的最大金额
  17. int[] result = new int[2];
  18. if(root == null){
  19. result[0] = 0;
  20. result[1] = 0;
  21. return result;
  22. }
  23. int[] l = dfs(root.left);
  24. int[] r = dfs(root.right);
  25. // 选择root时,最大金额就是root.val + 不选左右子节点时的最大金额
  26. result[0] = root.val + l[1] + r[1];
  27. // 而不选root时,最大金额为 Math.max(不选左子节点最大金额,选左子节点最大金额)
  28. // + Math.max(不选右子节点最大金额,选右子节点最大金额)
  29. // 考虑 [4,1,null,2,null,3]这样的左斜二叉树,
  30. // 最大金额为7,就是直接选根节点4和尾节点3的和,跳过中间1和2
  31. // 而不是说选了4就必须选2才是最大!!!
  32. // 注意这和打家劫舍1和2中不同,那里面dp[i]表示选或不选i时的最大金额
  33. // 而这里的i节点的l[0]就表示包含了i节点值的最大金额了
  34. // 所以必须分开考虑!
  35. result[1] = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
  36. return result;
  37. }
  38. }

2.3 时间复杂度

在这里插入图片描述
O(N)

  • 每个元素都遍历一次

2.4 空间复杂度

O(N)

  • 递归

参考文档

  • 树形 dp 入门问题(理解「无后效性」和「后序遍历」)
  • 三种方法解决树形动态规划问题-从入门级代码到高效树形动态规划代码实现

发表评论

表情:
评论列表 (有 0 条评论,78人围观)

还没有评论,来说两句吧...

相关阅读

    相关 序列类型动态规划——打家劫舍

    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自

    相关 725-打家劫舍(动态规划)

    打家劫舍(动态规划) 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在