借鉴DP思想: HouseRobberIII
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.
题目大意
给定一二叉树,树节点上有权值,从树中选取一些不直接相邻的节点,使得节点和最大
思考过程
1. 简单粗暴,搜索完事,一个节点不外乎两种情况,选择 or 不选择;另外当前节点选择之后,子节点不能被选择;当前节点若不选择,则又可以分为四种情况
* 左选择,右不选
* 右选,左不选
* 左右都选
* 左右都不选
2. 写代码,好的然而超时(当然-_-后来看了其他的解答,才发现too young)
3. 因为看到有重复计算,于是朝动态规划考虑,于是想出这么个状态
d[0][1],其中0表示存储遍历到当前节点时,取当前节点能达到的最大值,而1则表示,不取当前节点能达到的最大值
又因为是树节点,所以直接哈希表存储d[TreeNode*][]
4. 遍历顺序呢,习惯性后序遍历
5. 计算规则
// 显然,当前节点取了,子节点不能取
d[TreeNode*][0] = TreeNodeVal + d[LeftChild][1] + d[RightChild][1]
// 四种情况
d[TreeNode*][1] = max(d[LeftChild][0] + d[RightChild][0], d[LeftChild][1] + d[RightChild][0], d[LeftChild][0] + d[RightChild][1], d[LeftChild][1] + d[RightChild][1])
6. 总算过了,附代码;看了讨论的思路之后,觉得真是too young,╮(╯▽╰)╭
1 class Solution { 2 public: 3 int rob(TreeNode* root) { 4 if (root == NULL) { 5 return 0; 6 } 7 8 postOrder(root); 9 return max(d[root][0], d[root][1]); 10 } 11 12 void postOrder(TreeNode* itr) { 13 if (itr == NULL) { 14 return; 15 } 16 17 postOrder(itr->left); 18 postOrder(itr->right); 19 20 auto dItr = d.insert(pair<TreeNode*, vector<int>>(itr, vector<int>(2, 0))); 21 auto leftItr = dItr.first->first->left; 22 auto rightItr = dItr.first->first->right; 23 24 int rL = dItr.first->first->left != NULL ? d[dItr.first->first->left][0] : 0; 25 int rR = dItr.first->first->right != NULL ? d[dItr.first->first->right][0] : 0; 26 int uL = dItr.first->first->left != NULL ? d[dItr.first->first->left][1] : 0; 27 int uR = dItr.first->first->right != NULL ? d[dItr.first->first->right][1] : 0; 28 29 dItr.first->second[0] = dItr.first->first->val + uL + uR; 30 dItr.first->second[1] = max(max(max(rL + uR, uL + rR), rL + rR), uL + uR); 31 } 32 33 private: 34 unordered_map<TreeNode*, vector<int>> d; 35 };