基于二叉树的抢劫问题 leetcode337

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 
11 class Solution {
12 public:
13     int rob(TreeNode* root) {
14         return back(root)->val;
15     }
16 private:
17 struct DPnode {
18     int val;
19     int lsval;
20 };
21     DPnode* back(TreeNode* root) {
22         DPnode* dpn = new DPnode;
23         if (!root) {
24             dpn->val = 0;
25             dpn->lsval = 0;
26             return dpn;
27         }
28         DPnode* dpl = back(root->left);
29         DPnode* dpr = back(root->right);
30         int lr = dpl->val + dpr->val;
31         int llr = dpl->lsval + dpr->lsval;
32         if (lr > llr + root->val) {     
33             dpn->val = lr;              //not select this node
34         }else {
35             dpn->val = llr + root->val;
36         }
37         dpn->lsval = lr;
38         return dpn;
39     }
40 };

一维抢劫问题的DP方程:dp[i] = max{dp[i-1], dp[i-2] + vi};

如果数据结构是二叉树,比较适合从下往上后续遍历

本结点的左右子结点(对应一维的dp[i-1]):dplv,dprv

子结点的子结点(对应一维的dp[i-2]):lastdplv,lastdprv

因为树不好直接访问,每个节点需要保留以上两个值

方程:dpv = max{dplv + dprv, v + lastdplv + lastdprv};

本结点不选,选本结点的左右子树节点dplv + dprv

或者选本结点,并选左右子树节点的左右子结点:v + lastdplv + lastdprv

本结点的子结点dp:lastdpv = dplv + dprv;

猜你喜欢

转载自www.cnblogs.com/jkserge/p/9318467.html