刷題-力扣-337. 打家劫舍 III
阿新 • • 發佈:2021-06-28
337. 打家劫舍 III
題目連結
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/house-robber-iii
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
題目描述
在上次打劫完一條街道之後和一圈房屋後,小偷又發現了一個新的可行竊的地區。這個地區只有一個入口,我們稱之為“根”。 除了“根”之外,每棟房子有且只有一個“父“房子與之相連。一番偵察之後,聰明的小偷意識到“這個地方的所有房屋的排列類似於一棵二叉樹”。 如果兩個直接相連的房子在同一天晚上被打劫,房屋將自動報警。
計算在不觸動警報的情況下,小偷一晚能夠盜取的最高金額。
示例 1:
輸入: [3,2,3,null,3,null,1]
3
/ \
2 3
\ \
3 1
輸出: 7
解釋:小偷一晚能夠盜取的最高金額 = 3 + 3 + 1 = 7.
示例 2:
輸入: [3,4,5,1,3,null,1]
3
/ \
4 5
/ \ \
1 3 1
輸出: 9
解釋:小偷一晚能夠盜取的最高金額= 4 + 5 = 9.
題目分析
- 根據題目描述,計算不相連節點的最大權值和
- 假設f(x)表示選擇節點x的情況下最大權值和,g(x)表示不選擇節點x的情況下最大權值和
- 節點x的最大權值和有如下狀態轉移方程
f(x)=x->val+g(x->left)+g(x->right)
g(x)=max(g(x->left),f(x->left))+max(g(x->right),f(x->right))
程式碼
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { private: unordered_map<TreeNode*, int> f, g; public: int rob(TreeNode* root) { dfs(root); return max(f[root], g[root]); } private: void dfs(TreeNode* root) { if (!root) return; dfs(root->left); dfs(root->right); f[root] = root->val + g[root->left] + g[root->right]; g[root] = max(f[root->left], g[root->left]) + max(f[root->right], g[root->right]); } };