题目

image.png

思路

  • 思路一:暴力递归,对于每个节点来说,如果我们选择该节点,就不能选择其子节点,如果不选择该节点就能选择其子节点,所以只要选取这几种情况的最大值即可
  • 思路二:备忘录
  • 思路三:动态规划,对于一棵树来说,选择就如暴力递归一样有两种选择,因此定义int[] res = new int[2],res[0]表示不选取该节点能够获得的最大值,res[1]节点表示选取该节点能够获取的最大值,然后使用后续遍历节点,最后的到res结果,我们再去其最大值即可

    代码

    1. //1.暴力递归
    2. public int rob(TreeNode root) {
    3. if (root == null) return 0;
    4. return Math.max(
    5. (root.left != null ? rob(root.left.left) + rob(root.left.right) : 0) +
    6. (root.right != null ? rob(root.right.left) + rob(root.right.right) : 0) + root.val,
    7. rob(root.left) + rob(root.right));
    8. }
    9. //2.备忘录
    10. Map<TreeNode, Integer> map = new HashMap<>();
    11. public int rob(TreeNode root) {
    12. if (root == null) return 0;
    13. if (map.containsKey(root)) return map.get(root);
    14. int res = Math.max(
    15. (root.left != null ? rob(root.left.left) + rob(root.left.right) : 0) +
    16. (root.right != null ? rob(root.right.left) + rob(root.right.right) : 0) + root.val,
    17. rob(root.left) + rob(root.right));
    18. map.put(root, res);
    19. return res;
    20. }
    21. //3.动态规划
    22. public int rob(TreeNode root) {
    23. if (root == null) return 0;
    24. int[] res = recur(root);
    25. return Math.max(res[0], res[1]);
    26. }
    27. //res[0]表示不抢劫当前节点,res[1]表示抢劫当前节点
    28. public int[] recur(TreeNode root) {
    29. if (root == null) return new int[2];
    30. int[] res = new int[2];
    31. int[] left = recur(root.left);
    32. int[] right = recur(root.right);
    33. res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
    34. res[1] = root.val + left[0] + right[0];
    35. return res;
    36. }

    打家劫舍 III