題目地址:House Robber III
題目簡介:
在上次打劫完一條街道之後和一圈房屋後,小偷又發現了一個新的可行竊的地區。
這個地區只有一個入口,我們稱之爲“根”。 除了“根”之外,每棟房子有且只有一個“父“房子與之相連。一番偵察之後,聰明的小偷意識到“這個地方的所有房屋的排列類似於一棵二叉樹”。
如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。計算在不觸動警報的情況下,小偷一晚能夠盜取的最高金額。
示例 1:
Input: [3,2,3,null,3,null,1]
3
/ \
2 3
\ \
3 1
輸出: 7
解釋: 小偷一晚能夠盜取的最高金額 = 3 + 3 + 1 = 7.
示例 2:
Input: [3,4,5,1,3,null,1]
3
/ \
4 5
/ \ \
1 3 1
輸出: 9 解釋: 小偷一晚能夠盜取的最高金額 = 4 + 5 = 9.
題目解析:
一直出謀劃策,我是不是就是從犯了,還好我自己沒一下子就想起來解法(好像很開心)。
1、超時的想法:
因爲不能偷兩個直接相連的房子,那麼在某層時。只需考慮下一層最大值和當前層和往下兩層(如果存在的話)最大值之和,哪個大選哪個。超時代碼如下:
class Solution {
public:
int rob(TreeNode* root) {
if (root == NULL)
return 0;
int temp = 0;
if (root -> left)
temp += rob(root -> left -> left) + rob(root -> left -> right);
if (root -> right)
temp += rob(root -> right -> left) + rob(root -> right -> right);
return max(root -> val + temp, rob(root -> left) + rob(root -> right));
}
};
上述超時原因是計算rob(root -> left)時,也計算了rob(root -> left -> left),造成了時間的浪費。
2、參考了這篇文章後,每次只需要檢查下已層搶和不搶的最大結果即可。即當前知道下一層的最大值和下兩層的最大值。那麼當前層的最大值便可以得到。
C++:
/**
* 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) {
if (root == NULL)
return 0;
return dfs(root)[1];
}
vector<int> dfs(TreeNode *root)
{
//ans[0]表示不搶這層的結果,ans[1]這層能達到的最大的效果
vector<int> ans(2, 0);
if (root != NULL)
{
vector<int> left_ans = dfs(root -> left);
vector<int> right_ans = dfs(root -> right);
ans[0] = left_ans[1] + right_ans[1];
ans[1] = max(root -> val + left_ans[0] + right_ans[0], ans[0]);
}
return ans;
}
};
Python:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(root) :
if not root : return [0, 0]
robLeft = dfs(root.left)
robRight = dfs(root.right)
norobCur = robLeft[1] + robRight[1]
robCur = max(robLeft[0] + robRight[0] + root.val, norobCur)
return [norobCur, robCur]
return dfs(root)[1]