leetcode : 337. House Robber III : 简单的树形DP

337. House Robber III

My Submissions
Total Accepted: 3244  Total Submissions: 8627  Difficulty: Medium

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:

     3
    / \
   2   3
    \   \ 
     3   1
Maximum amount of money the thief can rob =  3 +  3 +  1 =  7.

Example 2:

     3
    / \
   4   5
  / \   \ 
 1   3   1
Maximum amount of money the thief can rob =  4 +  5 =  9.

通过读题可以发现:这是一个dp问题,如果将子问题设为,子树的max money。那么两种情况取最大值:1,root本身和root后第二层的节点maxmoney之和;2,root后第一层节点的maxmoney之和。

public int find(TreeNode x,HashMap<TreeNode, Integer> bag){
		if(x==null)
			return 0;
		if(bag.containsKey(x))
			return bag.get(x);
		else {
			int tt=search(x,bag);
			bag.put(x, tt);
			return tt;
		}
	}
	public int search(TreeNode root,HashMap<TreeNode, Integer> bag) {
		if(root==null)
			return 0;
		if(root.left==null&&root.right==null){
			return root.val;
		}else{
			int twol=find(root.left,bag);
			int twor=find(root.right,bag);
			int threell=root.left==null?0:find(root.left.left,bag);
			int threelr=root.left==null?0:find(root.left.right,bag);
			int threerl=root.right==null?0:find(root.right.left,bag);
			int threerr=root.right==null?0:find(root.right.right,bag);
			return Math.max(root.val+threell+threelr+threerl+threerr, 
					twol+twor);
		}	
	}
	public int rob(TreeNode root) {
		HashMap<TreeNode, Integer> bag=new HashMap<>();
		return search(root,bag);
	}

我的这种写法本来可以少一个函数,就是将hashmap设置成全局变量,但是那样的算法在java里面非常不容易维护的。因此使用hashmap作为参数,java中的参数都是引用,所以里面的值也是更改的。

还有一种更为巧妙地方法,时间复杂度没有变化,节省了hashmap的空间。这种能够方法每个节点设置了两个值,表示包含root节点的maxmoney和不包含的maxmoney,组后结果取两者最大值。

public int rob(TreeNode root) {
    int[] res = robSub(root);
    return Math.max(res[0], res[1]);
}

private int[] robSub(TreeNode root) {
    if (root == null) {
        return new int[2];
    }

    int[] left = robSub(root.left);
    int[] right = robSub(root.right);

    int[] res = new int[2];
    res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
    res[1] = root.val + left[0] + right[0];

    return res;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值