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;
    	}
    }
    

      



  • 相关阅读:
    ZOJ 3603字符串操作
    ZOJ 3609 求逆元
    HDOJ 4007 Dave【最大覆盖集】
    HDOJ4006 The kth great number 【串的更改和维护】
    【集训笔记】博弈论相关知识【HDOJ 1850【HDOJ2147
    【集训笔记】母函数【母函数模板】【HDOJ1028【HDOJ1085
    【集训笔记】【大数模板】特殊的数 【Catalan数】【HDOJ1133【HDOJ1134【HDOJ1130
    【集训笔记】动态规划背包问题【HDOJ1421【HDOJ1058【HDOJ2546
    【集训笔记】动态规划【HDOJ1159【HDOJ1003
    【集训笔记】二分图及其应用【HDOJ1068【HDOJ1150【HDOJ1151
  • 原文地址:https://www.cnblogs.com/zebinlin/p/9809302.html
Copyright © 2011-2022 走看看