LeetCode 124. Binary Tree Maximum Path Sum
题目链接:https://leetcode.com/problems/binary-tree-maximum-path-sum/
题意:已知一棵二叉树每个节点的权值,求一条权值和最大的路径,路径至少包含一个节点,可以不包括根节点。
思路:树形dp
刚开始觉得指针表示不太方便,给每个节点赋一个下标,先遍历整棵树,获取每个节点的权值,再进行树形dp,$dp[u]$表示以在以点u为根的子树中,$u$为端点时的最短路径,设$v$为$u$的子节点,则$dp[u]=max(dp[u],dp[v]+val[u])$,$ans=max(ans,dp[u]+dp[v])$,但这样做算法的常数较大,相比之下要慢很多
/** * 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 dfs(TreeNode *u,int sum){ //节点的编号 cnt++; //以节点编号为索引的权值 val[cnt] = u->val; int p= cnt; //用编号相互存储 if(u->left){ int z=dfs(u->left,sum+u->left->val); g[p].push_back(z); g[z].push_back(p); } if(u->right){ int z=dfs(u->right,sum+u->right->val); g[p].push_back(z); g[z].push_back(p); } return p; } //树形dp void TreeDp(int pre,int u){ ans = max(ans,val[u]); dp[u]=val[u]; for(int i=0;i<g[u].size();i++){ if(g[u][i]!=pre){ TreeDp(u,g[u][i]); ans=max(ans,dp[u]+dp[g[u][i]]); dp[u]=max(dp[u],dp[g[u][i]]+val[u]); } } } int maxPathSum(TreeNode* root) { dfs(root,root->val); memset(dp,0,sizeof(dp)); TreeDp(-1,0); return ans; } private: int cnt=-1; int ans=-1e9; int dp[100004]; int val[100004]; vector<int> g[100005]; };
直接使用指针,一次递归就行了:
/** * 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 ToRoot(TreeNode *root,int &ans){ if(!root) return 0; int l =ToRoot(root->left,ans); int r =ToRoot(root->right,ans); if(l<0) l=0; if(r<0) r=0; ans=max(ans,l+r+root->val); return root->val+max(l,r); } int maxPathSum(TreeNode* root) { int ans=-1e9; ToRoot(root,ans); return ans; } };