leetcode解题: House Robber III (337)

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:

1
2
3
4
5
3
/ \
2 3
\ \
3 1

Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:

1
2
3
4
5
3
/ \
4 5
/ \ \
1 3 1

Maximum amount of money the thief can rob = 4 + 5 = 9.

解法1:

参考了这个帖子的解法3。 对于每一个节点,存在两种可能, 取或者不取。 那么可以用一个帮助函数,每一次计算的时候保存这两种情况的值。
用一个vector保存,v[0]表示从这个点出发,不包含这个点最大的可取值, v1表示从这个点出发并且包含这个点可取的最大值。
那么对于一个root, 分别计算left和right的vector,再按取或者不取的情况计算出root的vector。
如果取root的值,那一定不能取left和right的值, 所以最大取值是left1 + right1 + val
如果不取root的值,那可以取left和right的值, 这也等价于两颗树,对这两颗树取这个问题的最大值,就是left两种情况的最大值+right两种情况的最大值。
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
vector<int> temp = helper(root);
return max(temp[0], temp[1]);
}
vector<int> helper(TreeNode* root) {
if (!root) {
return vector<int>(2, 0);
}
vector<int> left = helper(root->left);
vector<int> right = helper(root->right);
vector<int> res(2,0);
res[0] = max(left[0], left[1]) + max(right[0], right[1]);
res[1] = left[0] + right[0] + root->val;
return res;
}
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
class MarkedTreeNode {
int take;
int notake;
public MarkedTreeNode(int take, int notake) {
this.take = take;
this.notake = notake;
}
};
public int rob(TreeNode root) {
if (root == null) return 0;
MarkedTreeNode res = helper(root);
return Math.max(res.take, res.notake);
}
private MarkedTreeNode helper(TreeNode root) {
if (root == null) return new MarkedTreeNode(0,0);
MarkedTreeNode left = helper(root.left);
MarkedTreeNode right = helper(root.right);
int take = root.val + left.notake + right.notake;
int notake = Math.max(left.notake, left.take) + Math.max(right.notake, right.take);
return new MarkedTreeNode(take, notake);
}
}