zoukankan      html  css  js  c++  java
  • 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;
            
        }
        
        
    }
  • 相关阅读:
    06-继承与多态(动手动脑与验证)
    课堂测试四(文件读写)
    字符串加密
    String方法阅读笔记
    03-类与对象(动手动脑)
    计算已经创建了多少个对象
    递归练习(课程作业)
    02-方法(动手动脑)
    猜数字游戏
    JAVA语言实现简单登录界面
  • 原文地址:https://www.cnblogs.com/hwd9654/p/11361463.html
Copyright © 2011-2022 走看看