zoukankan      html  css  js  c++  java
  • [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.


    这次小偷偷的是一个二叉树型的小区,触发报警器的条件依然是相邻的房子同时失窃,即直接相连的两个节点(房子)同时失窃,问如何在不触发报警的条件下,能偷窃的最大金额。

    该题是House Robber I 和House Robber II 的拓展,依然可以利用动态规划的方法解决此题。具体思路如下:

      对于根节点而言,有两种状态:偷,不偷。因此可以用一个数组maxMoney[2]来分别记录偷、不偷该根节点所能获得的最高价值
      其中maxMoney[0]表示偷该节点所能获得的最高价值,maxMoney[1]表示不偷该节点所能获得的最高价值
      二叉树常用分治法,可将根节点的问题,转化为左右子树的问题
      分析可知,根节点的maxMoney[]数组是由其左右子树的leftMaxMoney[]和rightMaxMoney[]确定的
      具体为:
         maxMoney[0](偷) = leftMaxMoney[1](不偷左子节点) + rightMaxMoney[1](不偷右子节点) + root.val(偷该根节点)
         maxMoney[1](不偷) = max(leftMaxMoney[0],leftMaxMoney[1]) + max(rightMaxMoney[0],rightMaxMoney[1])

    class Solution {
        public int rob(TreeNode root) {
    		int[] res = helper(root);
    		return Math.max(res[0], res[1]);
    	}
    	/**
    	 * 对于根节点而言,有两种状态:偷,不偷。因此可以用一个数组maxMoney[2]来分别记录偷、不偷该根节点所能获得的最高价值
    	 * 其中maxMoney[0]表示偷该节点所能获得的最高价值
    	 * maxMoney[1]表示不偷该节点所能获得的最高价值
    	 * 二叉树常用分治法,可将根节点的问题,转化为左右子树的问题
    	 * 分析可知,根节点的maxMoney[]数组是由其左右子树的leftMaxMoney[]和rightMaxMoney[]确定的
    	 * 具体为:
    	 * 	maxMoney[0](偷) =  leftMaxMoney[1](不偷左子节点) + rightMaxMoney[1](不偷右子节点) + root.val(偷该根节点)
    	 * 	maxMoney[1](不偷) = max(leftMaxMoney[0],leftMaxMoney[1]) + max(rightMaxMoney[0],rightMaxMoney[1])
    	 * @param root 根节点
    	 * @return 数组maxMoney[2]分别记录以该节点位根,偷、不偷该根节点所能获得的最高价值
    	 */
    	public int[] helper(TreeNode root) {
    		if(root == null) {
    			int[] maxMoney = new int[]{0,0};
    			return maxMoney;
    		}
    		int[] maxMoney = new int[2];
    		int[] leftMaxMoney = helper(root.left);
    		int[] rightMaxMoney = helper(root.right);
    		maxMoney[0] = leftMaxMoney[1] +  rightMaxMoney[1] + root.val;
    		maxMoney[1] = Math.max(leftMaxMoney[0],leftMaxMoney[1])
    					+ Math.max(rightMaxMoney[0],rightMaxMoney[1]);
    		return maxMoney;
    	}
    }
    

      



  • 相关阅读:
    pr 打印函数
    list to tree(记录集转换为树结构)
    iOS 中计时器的使用心得
    iOS动画开发----打分 数字滚动刷新动画
    iOS动画开发----粒子系统---彩带效果
    Touch Up Inside not working with UISlider
    Xcode警告:Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
    iOS评论App----常用时间的处理
    获取文件/文件系统属性的方法----attributesOfItemAtPath:和attributesOfFileSystemForPath:
    NSInvocation错误
  • 原文地址:https://www.cnblogs.com/zebinlin/p/9809302.html
Copyright © 2011-2022 走看看