• [LeetCode] 337. House Robber III


    The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.

    Determine the maximum amount of money the thief can rob tonight without alerting the police.

    Example 1:

    Input: [3,2,3,null,3,null,1]
    
         3
        / 
       2   3
            
         3   1
    
    Output: 7 
    Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.

    Example 2:

    Input: [3,4,5,1,3,null,1]
    
         3
        / 
       4   5
      /     
     1   3   1
    
    Output: 9
    Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.

    打家劫舍III。题意跟前两个版本差不多,但是这次,小偷的目标换到一棵树了。给了一个树的根节点root,规则是不能偷相邻两层的节点上的房子。问最大收益是多少。

    我这里提供几种思路,代码执行速度由慢到快,都值得掌握。我参考了这个帖子

    首先是比较朴素的递归。思路是如果偷了根节点的房子,则不能偷儿子节点。最后判断的是到底是从根节点偷的收益大还是从儿子节点偷的收益大。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int rob(TreeNode root) {
     3         // corner case
     4         if (root == null) {
     5             return 0;
     6         }
     7 
     8         // normal case
     9         int money = root.val;
    10         if (root.left != null) {
    11             money += rob(root.left.left) + rob(root.left.right);
    12         }
    13         if (root.right != null) {
    14             money += rob(root.right.left) + rob(root.right.right);
    15         }
    16         return Math.max(money, rob(root.left) + rob(root.right));
    17     }
    18 }

    再来是记忆化递归。第一种解法中间有很多重复计算,需要用hashmap把中间过程的值记录下来。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int rob(TreeNode root) {
     3         HashMap<TreeNode, Integer> memo = new HashMap<>();
     4         return robInternal(root, memo);
     5     }
     6     
     7     public int robInternal(TreeNode root, HashMap<TreeNode, Integer> memo) {
     8         if (root == null) {
     9             return 0;
    10         }
    11         if (memo.containsKey(root)) {
    12             return memo.get(root);
    13         }
    14         int money = root.val;
    15         if (root.left != null) {
    16             money += (robInternal(root.left.left, memo) + robInternal(root.left.right, memo));
    17         }
    18         if (root.right != null) {
    19             money += (robInternal(root.right.left, memo) + robInternal(root.right.right, memo));
    20         }
    21         int res = Math.max(money, robInternal(root.left, memo) + robInternal(root.right, memo));
    22         memo.put(root, res);
    23         return res;
    24     }
    25 }

    最后是动态规划。创建一个数组,res[0]表示不偷当前节点,res[1]表示偷当前节点。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int rob(TreeNode root) {
     3         int[] res = helper(root);
     4         // 当前节点不偷,偷
     5         return Math.max(res[0], res[1]);
     6     }
     7     
     8     private int[] helper(TreeNode root) {
     9         if (root == null) {
    10             return new int[2];
    11         }
    12         int[] left = helper(root.left);
    13         int[] right = helper(root.right);
    14         int[] res = new int[2];
    15         res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
    16         res[1] = root.val + left[0] + right[0];
    17         return res;
    18     }
    19 }

    LeetCode 题目总结

  • 相关阅读:
    Eclipse解决Ctrl+c很卡的方法
    关于编程,大学没有传授的十件事-月光博客
    最牛B的编码套路
    (CareerCup)find the largest repetitive sequence
    (CareerCup)Find next higher number with same digits
    2013年HTML5峰会 一场守望者的盛宴
    Youzi2D推出开源HTML5游戏加速引擎
    HTML5与原生APP之争胜负已出?
    编程的未来
    拖拽即可创建HTML5网站的建站平台
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13437340.html
Copyright © 2020-2023  润新知