leetcode 337. House Robber III

先看递归的解法

无非就是取recur(root) + recur(root孙子节点)… 和 recur(root.left) + recur(root.right)的最大值

但是递归会反复求解之前求过的值,比如求recur(root.left)时又会重新求一遍recur(root孙子节点)

这个时候就可以利用dp的思想,备忘录方法,用一个HashMap<TreeNode, Integer>记录之前求过的节点。

 

class Solution {
    private HashMap<TreeNode, Integer> hash = new HashMap<>();
    public int rob(TreeNode root) {
        if(root == null)
            return 0;
        
        if(hash.containsKey(root))
            return hash.get(root);
        if(root.left == null && root.right == null){
            hash.put(root, root.val);
            return root.val;
        }
        if(root.left == null){
            int res = Math.max(root.val + rob(root.right.left) + rob(root.right.right), rob(root.right));
            hash.put(root, res);
            return res;
        }
        if(root.right == null){
            int res = Math.max(root.val + rob(root.left.left) + rob(root.left.right), rob(root.left));
            hash.put(root, res);
            return res;
        }
        int res = Math.max(root.val + rob(root.left.left) + rob(root.left.right) + rob(root.right.left) + rob(root.right.right), rob(root.left) + rob(root.right));
        hash.put(root, res);
        return res;
    }
    
}

还有没有更好的解法呢?

有,连这个hashmap也可以去掉

我们可以把dp[]改成2维,[0] 记录不rob当前节点的最大获利,[1]记录rob当前节点的最大获利。

class Solution {
    
    public int rob(TreeNode root) {
        if(root == null)
            return 0;
        int[] dp = new int[2];
        dp = helper(root);
        return Math.max(dp[0], dp[1]);
    }
    private int[] helper(TreeNode root){
        if(root == null)
            return new int[2];
        int[] res = new int[2];
        int[] left = helper(root.left);
        int[] right = helper(root.right);
        
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        res[1] = left[0] + right[0] + root.val;
        return res;
        
    }
    
    
}

 

posted @ 2019-08-16 01:20  南山南北秋悲  阅读(128)  评论(0编辑  收藏  举报