题目描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1 / \ 2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10 / \ 9 20 / \ 15 7
输出: 42
题解1:
二叉树 abc,a 是根结点(递归中的 root),bc 是左右子结点(代表其递归后的最优解)。
最大的路径,可能的路径情况:
a / \ b c
(1) b + a + c
(2) b + a + (a的父亲节点)
(3) c + a + (a的父亲节点)
//dfs返回左分支或者右分支的最大值(不包括第1种情况) int dfs(TreeNode* root, int val) { if(root==NULL) return 0; int left = dfs(root->left,val); int right = dfs(root->right,val); //第1种情况 int num_one = root->val+max(0,left)+max(0,right); //第2或者3情况 int num_two = root->val+max(0,max(left,right)); //保存可能的结果的最大值 val = max(val,max(num_one,num_two)); return num_two; }
题解2:
可以记录每个节点的直系父亲节点,然后将p节点的所有父节点加入一个集合S中,然后对q进行查询他的父节点是否在集合S中,当在时,则直接返回即可。
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { //建立子节点与父节点的映射关系 map<TreeNode*, TreeNode*> m; //遍历树节点 queue<TreeNode* > que; que.push(root); while(!que.empty()) { TreeNode* tmp = que.front(); que.pop(); if(tmp->left!=NULL) { m[tmp->left] = tmp; que.push(tmp->left); } if(tmp->right!=NULL) { m[tmp->right] = tmp; que.push(tmp->right); } } //p节点所有父亲节点集合 set<TreeNode* > S; S.insert(p); while(m.find(p)!=m.end()) { S.insert(m[p]); p = m[p]; } //看q的父亲节点是否在集合S中 if(s1.find(q)!=S.end()) return q; while(m.find(q)!=m.end()) { if(S.find(m[q])!=S.end()) return m[q]; q = m[q]; } return NULL; }