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

  



posted @ 2018-10-18 11:04  zebinLin  阅读(235)  评论(0编辑  收藏  举报