Stay button 337-- loot III

This one is based on the "loot" of expansion, need special consideration for special circumstances, of course, by its very nature is dynamic programming, data structures need to be considered when optimizing.

The original title

After completion of the last lap after robbing a street and house, he discovered a thief can steal new areas. The region has only one entrance, which we call the "root." In addition to the "root", and only the houses a "parent" house associated therewith. After some reconnaissance, clever thief realized that "this place all the houses are arranged similar to a binary tree." If both houses are directly connected robbed the same night, the house alarm.

Calculated without touching the alarm, a thief can steal the maximum amount of night.

Example 1:

输入: [3,2,3,null,3,null,1]

     3
    / \
   2   3
    \   \ 
     3   1

输出: 7 
解释: 小偷一晚能够盗取的最高金额 = 3   3   1 = 7.

Example 2:

输入: [3,4,5,1,3,null,1]

     3
    / \
   4   5
  / \   \ 
 1   3   1

输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4   5 = 9.

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

Problem-solving

Tree nodes given first:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

Simple ideas

This question Simply put, if there are 父节点、子节点、孙子节点three, then either steal 父节点 孙子节点or stealing only 子节点.

Along the way, we simply find the maximum value of each node can steal, naturally, will be able to find the maximum value began to steal from the root node.

Next we look at the code:

class Solution {

    Map<TreeNode, Integer> cache = new HashMap<>();

    public int rob(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // 是否已经计算过
        if (cache.containsKey(root)) {
            return cache.get(root);
        }

        // 策略1:抢当前节点和孙子节点
        int sum1 = root.val   
            // 左子节点的子节点们
            (root.left == null ? 0 : (rob(root.left.left)   rob(root.left.right)))  
            // 右子节点的子节点们
            (root.right == null ? 0 : (rob(root.right.left)   rob(root.right.right)));
        // 策略2:只抢子节点
        int sum2 = rob(root.left)   rob(root.right);
        // 找出更大的值
        int sum = Math.max(sum1, sum2);
        // 并记录
        cache.put(root, sum);
        return sum;
    }
}

Submit OK, when execution: 5 msonly defeated 52.00%the java submit records, so they still would benefit from optimization.

optimization

The above solution, if there is anything worthy of optimization of place, is that we are in a dynamic planning, taking into account not only the child nodes, even taking into account the grandson nodes, so when the child becomes a parent node, the node has become a grandson child nodes.

In other words, at the beginning of 孙子节点being counted twice. Although we borrowed a map to record intermediate results, but we need to note that this case will still be calculated, but the cost is transferred to the operation for the map, which is time-consuming.

So now optimized, it is converted to an intermediate state for the record on.

In fact, we focused on the status of each node only needs to record two situations: grab or not grab. And the state will only be used parent, it does not require permanent. Therefore, we consider an array of records with a length of 2, which will be much faster.

Next we look at the code:

class Solution {
    public int rob(TreeNode root) {
        // index为0,代表不抢当前节点的最大值
        // index为1,代表抢当前节点,不抢子节点的最大值
        int[] res = dp(root);
        return Math.max(res[0], res[1]);

    }

    public int[] dp(TreeNode cur) {
        if(cur == null) {
            return new int[]{0,0};
        }
        
        int[] left = dp(cur.left);
        int[] right = dp(cur.right);
        // 抢当前节点,子节点都不抢
        int rob = cur.val   left[0]  right[0];
        // 不抢当前节点,获取左右子节点各自的最大值
        int notRob = Math.max(left[0], left[1])   Math.max(right[0], right[1]);
        // 返回结果 
        return new int[]{notRob, rob};

    }
}

Submit OK, time consuming and only 1 msreally a lot faster.

to sum up

This question is above my answer process, I do not know if you understand. This question is mainly the use of dynamic programming, but we need to be thinking transformation, to consider when optimizing more understanding of data structures.

Are interested can visit my blog or follow me number of public, headline number, maybe there will be surprises.

https://death00.github.io/

Public number: Jian Cheng Road

Published 119 original articles · won praise 45 · views 220 000 +

Guess you like

Origin blog.csdn.net/death05/article/details/104082558