📌  相关文章
📜  二叉树中节点的最大和,使得没有两个相邻

📅  最后修改于: 2022-05-13 01:57:16.800000             🧑  作者: Mango

二叉树中节点的最大和,使得没有两个相邻

给定一个与每个节点相关联的值的二叉树,我们需要选择这些节点的子集,使得在子集中没有两个选择的节点不应该直接连接的约束下,选择的节点的总和最大,也就是说,如果我们已经在我们的总和中取了一个节点,那么我们就不能考虑它的任何子节点,反之亦然。

例子:

In above binary tree chosen nodes are encircled 
and are not directly connected and their sum is
maximum possible.

推荐:请先在“PRACTICE”上解决,然后再继续解决。

方法一
我们可以通过考虑节点及其子节点不能同时求和的事实来解决这个问题,所以当我们将一个节点纳入我们的总和时,我们将递归调用它的孙子节点,或者如果我们不接受这个节点然后我们将调用它的所有子节点,最后我们将从两个结果中选择最大值。
很容易看出,上述方法可以导致多次解决同一个子问题,例如在上图中,节点 1 在选择其值时调用节点 4 和节点 5,而在未选择其值时节点 3 也调用它们,所以这些节点被处理不止一次。我们可以通过记住所有节点的结果来多次停止求解这些节点。
在下面的代码中,映射用于存储结果,该结果存储以映射中节点为根的完整子树的结果,因此如果再次调用它,则不会再次计算该值,而是返回映射中存储的值直接地。

请参阅下面的代码以获得更好的理解。

C++
// C++ program to find maximum sum from a subset of
// nodes of binary tree
#include 
using namespace std;
 
/* A binary tree node structure */
struct node
{
    int data;
    struct node *left, *right;
};
 
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
    struct node *temp = new struct node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
//  Declaration of methods
int sumOfGrandChildren(node* node);
int getMaxSum(node* node);
int getMaxSumUtil(node* node, map& mp);
 
// method returns maximum sum possible from subtrees rooted
// at grandChildrens of node 'node'
int sumOfGrandChildren(node* node, map& mp)
{
    int sum = 0;
 
    //  call for children of left child only if it is not NULL
    if (node->left)
        sum += getMaxSumUtil(node->left->left, mp) +
               getMaxSumUtil(node->left->right, mp);
 
    //  call for children of right child only if it is not NULL
    if (node->right)
        sum += getMaxSumUtil(node->right->left, mp) +
               getMaxSumUtil(node->right->right, mp);
 
    return sum;
}
 
//  Utility method to return maximum sum rooted at node 'node'
int getMaxSumUtil(node* node, map& mp)
{
    if (node == NULL)
        return 0;
 
    // If node is already processed then return calculated
    // value from map
    if (mp.find(node) != mp.end())
        return mp[node];
 
    //  take current node value and call for all grand children
    int incl = node->data + sumOfGrandChildren(node, mp);
 
    //  don't take current node value and call for all children
    int excl = getMaxSumUtil(node->left, mp) +
               getMaxSumUtil(node->right, mp);
 
    //  choose maximum from both above calls and store that in map
    mp[node] = max(incl, excl);
 
    return mp[node];
}
 
// Returns maximum sum from subset of nodes
// of binary tree under given constraints
int getMaxSum(node* node)
{
    if (node == NULL)
        return 0;
    map mp;
    return getMaxSumUtil(node, mp);
}
 
//  Driver code to test above methods
int main()
{
    node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->right->left = newNode(4);
    root->right->right = newNode(5);
    root->left->left = newNode(1);
 
    cout << getMaxSum(root) << endl;
    return 0;
}


Java
// Java program to find maximum sum from a subset of
// nodes of binary tree
import java.util.HashMap;
public class FindSumOfNotAdjacentNodes {
 
    // method returns maximum sum possible from subtrees rooted
    // at grandChildrens of node 'node'
    public static int sumOfGrandChildren(Node node, HashMap mp)
    {
        int sum = 0;
        //  call for children of left child only if it is not NULL
        if (node.left!=null)
            sum += getMaxSumUtil(node.left.left, mp) +
                   getMaxSumUtil(node.left.right, mp);
   
        //  call for children of right child only if it is not NULL
        if (node.right!=null)
            sum += getMaxSumUtil(node.right.left, mp) +
                   getMaxSumUtil(node.right.right, mp);
        return sum;
    }
 
    //  Utility method to return maximum sum rooted at node 'node'
    public static int getMaxSumUtil(Node node, HashMap mp)
    {
        if (node == null)
            return 0;
   
        // If node is already processed then return calculated
        // value from map
        if(mp.containsKey(node))
            return mp.get(node);
   
        //  take current node value and call for all grand children
        int incl = node.data + sumOfGrandChildren(node, mp);
   
        //  don't take current node value and call for all children
        int excl = getMaxSumUtil(node.left, mp) +
                   getMaxSumUtil(node.right, mp);
   
        //  choose maximum from both above calls and store that in map
        mp.put(node,Math.max(incl, excl));
   
        return mp.get(node);
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int getMaxSum(Node node)
    {
        if (node == null)
            return 0;
        HashMap mp=new HashMap<>();
        return getMaxSumUtil(node, mp);
    }
 
    public static void main(String args[])
    {
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.right.left = new Node(4);
        root.right.right = new Node(5);
        root.left.left = new Node(1);    
        System.out.print(getMaxSum(root));
    }
}
 
/* A binary tree node structure */
class Node
{
    int data;
    Node left, right;
    Node(int data)
    {
        this.data=data;
        left=right=null;
    }
};
//This code is contributed by Gaurav Tiwari


Python3
# Python3 program to find
# maximum sum from a subset
# of nodes of binary tree
 
# A binary tree node structure
class Node:
     
    def __init__(self, data):
     
        self.data = data
        self.left = None
        self.right = None
 
# Utility function to create
# a new Binary Tree node
def newNode(data):
 
    temp = Node(data)
    return temp;
 
# method returns maximum sum
# possible from subtrees rooted
# at grandChildrens of node 'node'
def sumOfGrandChildren(node, mp):
 
    sum = 0;
 
    # call for children of left
    # child only if it is not NULL
    if (node.left):
        sum += (getMaxSumUtil(node.left.left, mp) +
                getMaxSumUtil(node.left.right, mp));
 
    # call for children of right
    # child only if it is not NULL
    if (node.right):
        sum += (getMaxSumUtil(node.right.left, mp) +
                getMaxSumUtil(node.right.right, mp));
 
    return sum;
 
# Utility method to return
# maximum sum rooted at node
# 'node'
def getMaxSumUtil(node, mp):
 
    if (node == None):
        return 0;
 
    # If node is already processed
    # then return calculated
    # value from map
    if node in mp:
        return mp[node];
 
    # take current node value
    # and call for all grand children
    incl = (node.data +
            sumOfGrandChildren(node, mp));
 
    # don't take current node
    # value and call for all children
    excl = (getMaxSumUtil(node.left, mp) +
            getMaxSumUtil(node.right, mp));
 
    # choose maximum from both
    # above calls and store that
    # in map
    mp[node] = max(incl, excl);
 
    return mp[node];
 
# Returns maximum sum from
# subset of nodes of binary
# tree under given constraints
def getMaxSum(node):
 
    if (node == None):
        return 0;
     
    mp = dict()
    return getMaxSumUtil(node, mp);
 
# Driver code
if __name__=="__main__":
     
    root = newNode(1);
    root.left = newNode(2);
    root.right = newNode(3);
    root.right.left = newNode(4);
    root.right.right = newNode(5);
    root.left.left = newNode(1);
     
    print(getMaxSum(root))
     
# This code is contributed by Rutvik_56


C#
// C# program to find maximum sum from a subset of
// nodes of binary tree
using System;
using System.Collections.Generic;
 
public class FindSumOfNotAdjacentNodes
{
 
    // method returns maximum sum
    // possible from subtrees rooted
    // at grandChildrens of node 'node'
    public static int sumOfGrandChildren(Node node,
                            Dictionary mp)
    {
        int sum = 0;
         
        // call for children of left
        // child only if it is not NULL
        if (node.left != null)
            sum += getMaxSumUtil(node.left.left, mp) +
                getMaxSumUtil(node.left.right, mp);
     
        // call for children of right
        // child only if it is not NULL
        if (node.right != null)
            sum += getMaxSumUtil(node.right.left, mp) +
                getMaxSumUtil(node.right.right, mp);
        return sum;
    }
 
    // Utility method to return maximum
    // sum rooted at node 'node'
    public static int getMaxSumUtil(Node node,
                        Dictionary mp)
    {
        if (node == null)
            return 0;
     
        // If node is already processed then
        // return calculated value from map
        if(mp.ContainsKey(node))
            return mp[node];
     
        // take current node value and
        // call for all grand children
        int incl = node.data + sumOfGrandChildren(node, mp);
     
        // don't take current node value and
        // call for all children
        int excl = getMaxSumUtil(node.left, mp) +
                getMaxSumUtil(node.right, mp);
     
        // choose maximum from both above
        // calls and store that in map
        mp.Add(node,Math.Max(incl, excl));
     
        return mp[node];
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int getMaxSum(Node node)
    {
        if (node == null)
            return 0;
        Dictionary mp=new Dictionary();
        return getMaxSumUtil(node, mp);
    }
 
    // Driver code
    public static void Main(String []args)
    {
        Node root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.right.left = new Node(4);
        root.right.right = new Node(5);
        root.left.left = new Node(1);    
        Console.Write(getMaxSum(root));
    }
}
 
/* A binary tree node structure */
public class Node
{
    public int data;
    public Node left, right;
    public Node(int data)
    {
        this.data=data;
        left=right=null;
    }
};
 
// This code has been contributed by 29AjayKumar


Javascript


C++
// C++ program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
#include
using namespace std;
 
class Node
{
public:
    int data;
    Node* left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
 
pair maxSumHelper(Node *root)
{
    if (root==NULL)
    {
        pair sum(0, 0);
        return sum;
    }
    pair sum1 = maxSumHelper(root->left);
    pair sum2 = maxSumHelper(root->right);
    pair sum;
 
    // This node is included (Left and right children
    // are not included)
    sum.first = sum1.second + sum2.second + root->data;
 
    // This node is excluded (Either left or right
    // child is included)
    sum.second = max(sum1.first, sum1.second) +
                 max(sum2.first, sum2.second);
 
    return sum;
}
 
int maxSum(Node *root)
{
    pair res = maxSumHelper(root);
    return max(res.first, res.second);
}
 
// Driver code
int main()
{
    Node *root= new Node(10);
    root->left= new Node(1);
    root->left->left= new Node(2);
    root->left->left->left= new Node(1);
    root->left->right= new Node(3);
    root->left->right->left= new Node(4);
    root->left->right->right= new Node(5);
    cout << maxSum(root);
    return 0;
}


Java
// Java program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
public class FindSumOfNotAdjacentNodes {
 
    public static Pair maxSumHelper(Node root)
    {
        if (root==null)
        {
            Pair sum=new Pair(0, 0);
            return sum;
        }
        Pair sum1 = maxSumHelper(root.left);
        Pair sum2 = maxSumHelper(root.right);
        Pair sum=new Pair(0,0);
   
        // This node is included (Left and right children
        // are not included)
        sum.first = sum1.second + sum2.second + root.data;
   
        // This node is excluded (Either left or right
        // child is included)
        sum.second = Math.max(sum1.first, sum1.second) +
                     Math.max(sum2.first, sum2.second);
   
        return sum;
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int maxSum(Node root)
    {
        Pair res=maxSumHelper(root);
        return Math.max(res.first, res.second);
    }
 
    public static void main(String args[]) {
        Node root= new Node(10);
        root.left= new Node(1);
        root.left.left= new Node(2);
        root.left.left.left= new Node(1);
        root.left.right= new Node(3);
        root.left.right.left= new Node(4);
        root.left.right.right= new Node(5);
        System.out.print(maxSum(root));
    }
}
 
/* A binary tree node structure */
class Node
{
    int data;
    Node left, right;
    Node(int data)
    {
        this.data=data;
        left=right=null;
    }
};
 
/* Pair class */
class Pair
{
    int first,second;
    Pair(int first,int second)
    {
        this.first=first;
        this.second=second;
    }
}
//This code is contributed by Gaurav Tiwari


Python3
# Python3 program to find maximum sum in Binary
# Tree such that no two nodes are adjacent.
 
# Binary Tree Node
 
""" utility that allocates a newNode
with the given key """
class newNode:
 
    # Construct to create a newNode
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
def maxSumHelper(root) :
 
    if (root == None):
     
        sum = [0, 0]
        return sum
     
    sum1 = maxSumHelper(root.left)
    sum2 = maxSumHelper(root.right)
    sum = [0, 0]
 
    # This node is included (Left and right
    # children are not included)
    sum[0] = sum1[1] + sum2[1] + root.data
 
    # This node is excluded (Either left or
    # right child is included)
    sum[1] = (max(sum1[0], sum1[1]) +
              max(sum2[0], sum2[1]))
 
    return sum
 
def maxSum(root) :
 
    res = maxSumHelper(root)
    return max(res[0], res[1])
 
# Driver Code
if __name__ == '__main__':
    root = newNode(10)
    root.left = newNode(1)
    root.left.left = newNode(2)
    root.left.left.left = newNode(1)
    root.left.right = newNode(3)
    root.left.right.left = newNode(4)
    root.left.right.right = newNode(5)
    print(maxSum(root))
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#
// C# program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
using System;
 
public class FindSumOfNotAdjacentNodes
{
 
    public static Pair maxSumHelper(Node root)
    {
        Pair sum;
        if (root == null)
        {
            sum=new Pair(0, 0);
            return sum;
        }
        Pair sum1 = maxSumHelper(root.left);
        Pair sum2 = maxSumHelper(root.right);
        Pair sum3 = new Pair(0,0);
     
        // This node is included (Left and
        // right children are not included)
        sum3.first = sum1.second + sum2.second + root.data;
     
        // This node is excluded (Either left
        // or right child is included)
        sum3.second = Math.Max(sum1.first, sum1.second) +
                    Math.Max(sum2.first, sum2.second);
     
        return sum3;
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int maxSum(Node root)
    {
        Pair res=maxSumHelper(root);
        return Math.Max(res.first, res.second);
    }
 
    // Driver code
    public static void Main()
    {
        Node root = new Node(10);
        root.left = new Node(1);
        root.left.left = new Node(2);
        root.left.left.left = new Node(1);
        root.left.right = new Node(3);
        root.left.right.left = new Node(4);
        root.left.right.right = new Node(5);
        Console.Write(maxSum(root));
    }
}
 
/* A binary tree node structure */
public class Node
{
    public int data;
    public Node left, right;
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
};
 
/* Pair class */
public class Pair
{
    public int first,second;
    public Pair(int first,int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
/* This code is contributed PrinciRaj1992 */


Javascript


C++
// C++ program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
#include 
#include 
using namespace std;
 
class Node {
public:
    int data;
    Node *left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
// declare map /dp array as global
unordered_map umap;
int maxSum(Node* root)
{
    // base case
    if (!root)
        return 0;
 
    // if the max sum from the  node is already in
    // map,return the value
    if (umap[root])
        return umap[root];
 
    // if the current node(root) is included in result
    // then find maximum sum
    int inc = root->data;
 
    // if left of node exists, add their grandchildren
    if (root->left) {
        inc += maxSum(root->left->left)
               + maxSum(root->left->right);
    }
    // if right of node exist,add their grandchildren
    if (root->right) {
        inc += maxSum(root->right->left)
               + maxSum(root->right->right);
    }
 
    // if the current node(root) is excluded, find the
    // maximum sum
    int ex = maxSum(root->left) + maxSum(root->right);
 
    // store the maximum of including & excluding the node
    // in map
    umap[root] = max(inc, ex);
    return max(inc, ex);
}
 
// Driver code
int main()
{
    Node* root = new Node(10);
    root->left = new Node(1);
    root->left->left = new Node(2);
    root->left->left->left = new Node(1);
    root->left->right = new Node(3);
    root->left->right->left = new Node(4);
    root->left->right->right = new Node(5);
    cout << maxSum(root);
    return 0;
}


Javascript


Python3
class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
 
 
class Solution:
 
    def max_sum(self, root):
        if not root:
            return 0, 0
 
        no_root_l, root_l = self.max_sum(root.left)
        no_root_r, root_r = self.max_sum(root.right)
 
        root_sum_max = max(root.data, root.data+no_root_l,
                           root.data+no_root_r, root.data+no_root_r+no_root_l)
        no_root_sum_max = max(root_l, root_r, root_l + root_r, no_root_l+no_root_r,
                              root_l + no_root_r, root_r + no_root_l)
 
        return no_root_sum_max, root_sum_max
 
    def getMaxSum(self, root):
        return max(self.max_sum(root))


输出
11

方法2(使用pair)
为二叉树中的每个节点返回一对,当包含节点的数据时,第一个表示最大和,当不包含特定节点的数据时,第二个表示最大和。

C++

// C++ program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
#include
using namespace std;
 
class Node
{
public:
    int data;
    Node* left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
 
pair maxSumHelper(Node *root)
{
    if (root==NULL)
    {
        pair sum(0, 0);
        return sum;
    }
    pair sum1 = maxSumHelper(root->left);
    pair sum2 = maxSumHelper(root->right);
    pair sum;
 
    // This node is included (Left and right children
    // are not included)
    sum.first = sum1.second + sum2.second + root->data;
 
    // This node is excluded (Either left or right
    // child is included)
    sum.second = max(sum1.first, sum1.second) +
                 max(sum2.first, sum2.second);
 
    return sum;
}
 
int maxSum(Node *root)
{
    pair res = maxSumHelper(root);
    return max(res.first, res.second);
}
 
// Driver code
int main()
{
    Node *root= new Node(10);
    root->left= new Node(1);
    root->left->left= new Node(2);
    root->left->left->left= new Node(1);
    root->left->right= new Node(3);
    root->left->right->left= new Node(4);
    root->left->right->right= new Node(5);
    cout << maxSum(root);
    return 0;
}

Java

// Java program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
public class FindSumOfNotAdjacentNodes {
 
    public static Pair maxSumHelper(Node root)
    {
        if (root==null)
        {
            Pair sum=new Pair(0, 0);
            return sum;
        }
        Pair sum1 = maxSumHelper(root.left);
        Pair sum2 = maxSumHelper(root.right);
        Pair sum=new Pair(0,0);
   
        // This node is included (Left and right children
        // are not included)
        sum.first = sum1.second + sum2.second + root.data;
   
        // This node is excluded (Either left or right
        // child is included)
        sum.second = Math.max(sum1.first, sum1.second) +
                     Math.max(sum2.first, sum2.second);
   
        return sum;
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int maxSum(Node root)
    {
        Pair res=maxSumHelper(root);
        return Math.max(res.first, res.second);
    }
 
    public static void main(String args[]) {
        Node root= new Node(10);
        root.left= new Node(1);
        root.left.left= new Node(2);
        root.left.left.left= new Node(1);
        root.left.right= new Node(3);
        root.left.right.left= new Node(4);
        root.left.right.right= new Node(5);
        System.out.print(maxSum(root));
    }
}
 
/* A binary tree node structure */
class Node
{
    int data;
    Node left, right;
    Node(int data)
    {
        this.data=data;
        left=right=null;
    }
};
 
/* Pair class */
class Pair
{
    int first,second;
    Pair(int first,int second)
    {
        this.first=first;
        this.second=second;
    }
}
//This code is contributed by Gaurav Tiwari

Python3

# Python3 program to find maximum sum in Binary
# Tree such that no two nodes are adjacent.
 
# Binary Tree Node
 
""" utility that allocates a newNode
with the given key """
class newNode:
 
    # Construct to create a newNode
    def __init__(self, key):
        self.data = key
        self.left = None
        self.right = None
 
def maxSumHelper(root) :
 
    if (root == None):
     
        sum = [0, 0]
        return sum
     
    sum1 = maxSumHelper(root.left)
    sum2 = maxSumHelper(root.right)
    sum = [0, 0]
 
    # This node is included (Left and right
    # children are not included)
    sum[0] = sum1[1] + sum2[1] + root.data
 
    # This node is excluded (Either left or
    # right child is included)
    sum[1] = (max(sum1[0], sum1[1]) +
              max(sum2[0], sum2[1]))
 
    return sum
 
def maxSum(root) :
 
    res = maxSumHelper(root)
    return max(res[0], res[1])
 
# Driver Code
if __name__ == '__main__':
    root = newNode(10)
    root.left = newNode(1)
    root.left.left = newNode(2)
    root.left.left.left = newNode(1)
    root.left.right = newNode(3)
    root.left.right.left = newNode(4)
    root.left.right.right = newNode(5)
    print(maxSum(root))
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

C#

// C# program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
using System;
 
public class FindSumOfNotAdjacentNodes
{
 
    public static Pair maxSumHelper(Node root)
    {
        Pair sum;
        if (root == null)
        {
            sum=new Pair(0, 0);
            return sum;
        }
        Pair sum1 = maxSumHelper(root.left);
        Pair sum2 = maxSumHelper(root.right);
        Pair sum3 = new Pair(0,0);
     
        // This node is included (Left and
        // right children are not included)
        sum3.first = sum1.second + sum2.second + root.data;
     
        // This node is excluded (Either left
        // or right child is included)
        sum3.second = Math.Max(sum1.first, sum1.second) +
                    Math.Max(sum2.first, sum2.second);
     
        return sum3;
    }
 
    // Returns maximum sum from subset of nodes
    // of binary tree under given constraints
    public static int maxSum(Node root)
    {
        Pair res=maxSumHelper(root);
        return Math.Max(res.first, res.second);
    }
 
    // Driver code
    public static void Main()
    {
        Node root = new Node(10);
        root.left = new Node(1);
        root.left.left = new Node(2);
        root.left.left.left = new Node(1);
        root.left.right = new Node(3);
        root.left.right.left = new Node(4);
        root.left.right.right = new Node(5);
        Console.Write(maxSum(root));
    }
}
 
/* A binary tree node structure */
public class Node
{
    public int data;
    public Node left, right;
    public Node(int data)
    {
        this.data = data;
        left = right = null;
    }
};
 
/* Pair class */
public class Pair
{
    public int first,second;
    public Pair(int first,int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
/* This code is contributed PrinciRaj1992 */

Javascript


输出
21

时间复杂度:O(n)
感谢 Surbhi Rastogi 提出这种方法。

方法3(使用动态规划

通过在 dp 数组或无序映射中包含节点或排除节点来存储最大和。如果包含节点,则递归调用节点的孙子节点,如果排除节点,则调用邻居。

C++

// C++ program to find maximum sum in Binary Tree
// such that no two nodes are adjacent.
#include 
#include 
using namespace std;
 
class Node {
public:
    int data;
    Node *left, *right;
    Node(int data)
    {
        this->data = data;
        left = NULL;
        right = NULL;
    }
};
// declare map /dp array as global
unordered_map umap;
int maxSum(Node* root)
{
    // base case
    if (!root)
        return 0;
 
    // if the max sum from the  node is already in
    // map,return the value
    if (umap[root])
        return umap[root];
 
    // if the current node(root) is included in result
    // then find maximum sum
    int inc = root->data;
 
    // if left of node exists, add their grandchildren
    if (root->left) {
        inc += maxSum(root->left->left)
               + maxSum(root->left->right);
    }
    // if right of node exist,add their grandchildren
    if (root->right) {
        inc += maxSum(root->right->left)
               + maxSum(root->right->right);
    }
 
    // if the current node(root) is excluded, find the
    // maximum sum
    int ex = maxSum(root->left) + maxSum(root->right);
 
    // store the maximum of including & excluding the node
    // in map
    umap[root] = max(inc, ex);
    return max(inc, ex);
}
 
// Driver code
int main()
{
    Node* root = new Node(10);
    root->left = new Node(1);
    root->left->left = new Node(2);
    root->left->left->left = new Node(1);
    root->left->right = new Node(3);
    root->left->right->left = new Node(4);
    root->left->right->right = new Node(5);
    cout << maxSum(root);
    return 0;
}

Javascript


输出
21

时间复杂度: O(n)
辅助空间: O(n)

如果您喜欢 GeeksforGeeks 并愿意做出贡献,您还可以使用 write.geeksforgeeks.org 撰写文章或将您的文章邮寄至 review-team@geeksforgeeks.org。在 GeeksforGeeks 主页上查看您的文章并帮助其他 Geeks。

方法四(简单树遍历)

对于每个节点,我们发现以下内容:

  1. 包括该节点的非相邻节点的最大总和。
  2. 除节点外的非相邻节点的最大总和。

现在,我们在递归调用中返回两个值。先前计算的节点的父节点获得最大和(包括&不包括)子节点。因此,父母现在计算最大总和(包括和排除)并返回。这个过程一直持续到根节点。最后,我们返回最大值(包括根的总和,不包括根的总和)。

时间复杂度:O(n)

空间复杂度:O(1)

Python3

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None
 
 
class Solution:
 
    def max_sum(self, root):
        if not root:
            return 0, 0
 
        no_root_l, root_l = self.max_sum(root.left)
        no_root_r, root_r = self.max_sum(root.right)
 
        root_sum_max = max(root.data, root.data+no_root_l,
                           root.data+no_root_r, root.data+no_root_r+no_root_l)
        no_root_sum_max = max(root_l, root_r, root_l + root_r, no_root_l+no_root_r,
                              root_l + no_root_r, root_r + no_root_l)
 
        return no_root_sum_max, root_sum_max
 
    def getMaxSum(self, root):
        return max(self.max_sum(root))

该方法由 Thatikonda Aditya 提供。