题目描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 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;
}
 京公网安备 11010502036488号
京公网安备 11010502036488号