借鉴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 };
View Code
原文地址:https://www.cnblogs.com/hzhesi/p/5281686.html