在二叉树中找到最大和叶到根路径
- 给定一棵二叉树,找到从叶子到根的最大和路径。例如,在下面的树中,有三个叶子到根的路径 8->-2->10、-4->-2->10 和 7->10。这三个路径的总和分别为 16、4 和 17。它们的最大值是 17,最大值的路径是 7->10。
10
/ \
-2 7
/ \
8 -4
解决方案
1)首先找到最大和路径上的叶子节点。在以下代码中,getTargetLeaf() 通过将结果分配给 *target_leaf_ref 来完成此操作。
2)一旦我们有了目标叶子节点,我们就可以通过遍历树来打印最大和路径。在下面的代码中, printPath() 执行此操作。
主要函数是 maxSumPath() ,它使用上述两个函数来获得完整的解决方案。
C++
// CPP program to find maximum sum leaf to root
// path in Binary Tree
#include
using namespace std;
/* A tree node structure */
class node {
public:
int data;
node* left;
node* right;
};
// A utility function that prints all nodes
// on the path from root to target_leaf
bool printPath(node* root,
node* target_leaf)
{
// base case
if (root == NULL)
return false;
// return true if this node is the target_leaf
// or target leaf is present in one of its
// descendants
if (root == target_leaf || printPath(root->left, target_leaf) ||
printPath(root->right, target_leaf)) {
cout << root->data << " ";
return true;
}
return false;
}
// This function Sets the target_leaf_ref to refer
// the leaf node of the maximum path sum. Also,
// returns the max_sum using max_sum_ref
void getTargetLeaf(node* Node, int* max_sum_ref,
int curr_sum, node** target_leaf_ref)
{
if (Node == NULL)
return;
// Update current sum to hold sum of nodes on path
// from root to this node
curr_sum = curr_sum + Node->data;
// If this is a leaf node and path to this node has
// maximum sum so far, then make this node target_leaf
if (Node->left == NULL && Node->right == NULL) {
if (curr_sum > *max_sum_ref) {
*max_sum_ref = curr_sum;
*target_leaf_ref = Node;
}
}
// If this is not a leaf node, then recur down
// to find the target_leaf
getTargetLeaf(Node->left, max_sum_ref, curr_sum,
target_leaf_ref);
getTargetLeaf(Node->right, max_sum_ref, curr_sum,
target_leaf_ref);
}
// Returns the maximum sum and prints the nodes on max
// sum path
int maxSumPath(node* Node)
{
// base case
if (Node == NULL)
return 0;
node* target_leaf;
int max_sum = INT_MIN;
// find the target leaf and maximum sum
getTargetLeaf(Node, &max_sum, 0, &target_leaf);
// print the path from root to the target leaf
printPath(Node, target_leaf);
return max_sum; // return maximum sum
}
/* Utility function to create a new Binary Tree node */
node* newNode(int data)
{
node* temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Driver function to test above functions */
int main()
{
node* root = NULL;
/* Constructing tree given in the above figure */
root = newNode(10);
root->left = newNode(-2);
root->right = newNode(7);
root->left->left = newNode(8);
root->left->right = newNode(-4);
cout << "Following are the nodes on the maximum "
"sum path \n";
int sum = maxSumPath(root);
cout << "\nSum of the nodes is " << sum;
return 0;
}
// This code is contributed by rathbhupendra
C
// C program to find maximum sum leaf to root
// path in Binary Tree
#include
#include
#include
#include
/* A tree node structure */
struct node {
int data;
struct node* left;
struct node* right;
};
// A utility function that prints all nodes
// on the path from root to target_leaf
bool printPath(struct node* root,
struct node* target_leaf)
{
// base case
if (root == NULL)
return false;
// return true if this node is the target_leaf
// or target leaf is present in one of its
// descendants
if (root == target_leaf || printPath(root->left, target_leaf) ||
printPath(root->right, target_leaf)) {
printf("%d ", root->data);
return true;
}
return false;
}
// This function Sets the target_leaf_ref to refer
// the leaf node of the maximum path sum. Also,
// returns the max_sum using max_sum_ref
void getTargetLeaf(struct node* node, int* max_sum_ref,
int curr_sum, struct node** target_leaf_ref)
{
if (node == NULL)
return;
// Update current sum to hold sum of nodes on path
// from root to this node
curr_sum = curr_sum + node->data;
// If this is a leaf node and path to this node has
// maximum sum so far, then make this node target_leaf
if (node->left == NULL && node->right == NULL) {
if (curr_sum > *max_sum_ref) {
*max_sum_ref = curr_sum;
*target_leaf_ref = node;
}
}
// If this is not a leaf node, then recur down
// to find the target_leaf
getTargetLeaf(node->left, max_sum_ref, curr_sum,
target_leaf_ref);
getTargetLeaf(node->right, max_sum_ref, curr_sum,
target_leaf_ref);
}
// Returns the maximum sum and prints the nodes on max
// sum path
int maxSumPath(struct node* node)
{
// base case
if (node == NULL)
return 0;
struct node* target_leaf;
int max_sum = INT_MIN;
// find the target leaf and maximum sum
getTargetLeaf(node, &max_sum, 0, &target_leaf);
// print the path from root to the target leaf
printPath(node, target_leaf);
return max_sum; // return maximum sum
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Driver function to test above functions */
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure */
root = newNode(10);
root->left = newNode(-2);
root->right = newNode(7);
root->left->left = newNode(8);
root->left->right = newNode(-4);
printf("Following are the nodes on the maximum "
"sum path \n");
int sum = maxSumPath(root);
printf("\nSum of the nodes is %d ", sum);
getchar();
return 0;
}
Java
// Java program to find maximum sum leaf to root
// path in Binary Tree
// A Binary Tree node
class Node {
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
// A wrapper class is used so that max_no
// can be updated among function calls.
class Maximum {
int max_no = Integer.MIN_VALUE;
}
class BinaryTree {
Node root;
Maximum max = new Maximum();
Node target_leaf = null;
// A utility function that prints all nodes on the
// path from root to target_leaf
boolean printPath(Node node, Node target_leaf)
{
// base case
if (node == null)
return false;
// return true if this node is the target_leaf or
// target leaf is present in one of its descendants
if (node == target_leaf || printPath(node.left, target_leaf)
|| printPath(node.right, target_leaf)) {
System.out.print(node.data + " ");
return true;
}
return false;
}
// This function Sets the target_leaf_ref to refer
// the leaf node of the maximum path sum. Also,
// returns the max_sum using max_sum_ref
void getTargetLeaf(Node node, Maximum max_sum_ref,
int curr_sum)
{
if (node == null)
return;
// Update current sum to hold sum of nodes on
// path from root to this node
curr_sum = curr_sum + node.data;
// If this is a leaf node and path to this node
// has maximum sum so far, the n make this node
// target_leaf
if (node.left == null && node.right == null) {
if (curr_sum > max_sum_ref.max_no) {
max_sum_ref.max_no = curr_sum;
target_leaf = node;
}
}
// If this is not a leaf node, then recur down
// to find the target_leaf
getTargetLeaf(node.left, max_sum_ref, curr_sum);
getTargetLeaf(node.right, max_sum_ref, curr_sum);
}
// Returns the maximum sum and prints the nodes on
// max sum path
int maxSumPath()
{
// base case
if (root == null)
return 0;
// find the target leaf and maximum sum
getTargetLeaf(root, max, 0);
// print the path from root to the target leaf
printPath(root, target_leaf);
return max.max_no; // return maximum sum
}
// driver function to test the above functions
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(-2);
tree.root.right = new Node(7);
tree.root.left.left = new Node(8);
tree.root.left.right = new Node(-4);
System.out.println("Following are the nodes "
+ "on maximum sum path");
int sum = tree.maxSumPath();
System.out.println("");
System.out.println("Sum of nodes is : " + sum);
}
}
// This code has been contributed by Mayank Jaiswal
Python3
# Python3 program to find maximum sum leaf to root
# path in Binary Tree
# A tree node structure
class node :
def __init__(self):
self.data = 0
self.left = None
self.right = None
# A utility function that prints all nodes
# on the path from root to target_leaf
def printPath( root,target_leaf):
# base case
if (root == None):
return False
# return True if this node is the target_leaf
# or target leaf is present in one of its
# descendants
if (root == target_leaf or
printPath(root.left, target_leaf) or
printPath(root.right, target_leaf)) :
print( root.data, end = " ")
return True
return False
max_sum_ref = 0
target_leaf_ref = None
# This function Sets the target_leaf_ref to refer
# the leaf node of the maximum path sum. Also,
# returns the max_sum using max_sum_ref
def getTargetLeaf(Node, curr_sum):
global max_sum_ref
global target_leaf_ref
if (Node == None):
return
# Update current sum to hold sum of nodes on path
# from root to this node
curr_sum = curr_sum + Node.data
# If this is a leaf node and path to this node has
# maximum sum so far, then make this node target_leaf
if (Node.left == None and Node.right == None):
if (curr_sum > max_sum_ref) :
max_sum_ref = curr_sum
target_leaf_ref = Node
# If this is not a leaf node, then recur down
# to find the target_leaf
getTargetLeaf(Node.left, curr_sum)
getTargetLeaf(Node.right, curr_sum)
# Returns the maximum sum and prints the nodes on max
# sum path
def maxSumPath( Node):
global max_sum_ref
global target_leaf_ref
# base case
if (Node == None):
return 0
target_leaf_ref = None
max_sum_ref = -32676
# find the target leaf and maximum sum
getTargetLeaf(Node, 0)
# print the path from root to the target leaf
printPath(Node, target_leaf_ref);
return max_sum_ref; # return maximum sum
# Utility function to create a new Binary Tree node
def newNode(data):
temp = node();
temp.data = data;
temp.left = None;
temp.right = None;
return temp;
# Driver function to test above functions
root = None;
# Constructing tree given in the above figure
root = newNode(10);
root.left = newNode(-2);
root.right = newNode(7);
root.left.left = newNode(8);
root.left.right = newNode(-4);
print( "Following are the nodes on the maximum sum path ");
sum = maxSumPath(root);
print( "\nSum of the nodes is " , sum);
# This code is contributed by Arnab Kundu
C#
using System;
// C# program to find maximum sum leaf to root
// path in Binary Tree
// A Binary Tree node
public class Node {
public int data;
public Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
}
// A wrapper class is used so that max_no
// can be updated among function calls.
public class Maximum {
public int max_no = int.MinValue;
}
public class BinaryTree {
public Node root;
public Maximum max = new Maximum();
public Node target_leaf = null;
// A utility function that prints all nodes on the
// path from root to target_leaf
public virtual bool printPath(Node node, Node target_leaf)
{
// base case
if (node == null) {
return false;
}
// return true if this node is the target_leaf or
// target leaf is present in one of its descendants
if (node == target_leaf || printPath(node.left, target_leaf)
|| printPath(node.right, target_leaf)) {
Console.Write(node.data + " ");
return true;
}
return false;
}
// This function Sets the target_leaf_ref to refer
// the leaf node of the maximum path sum. Also,
// returns the max_sum using max_sum_ref
public virtual void getTargetLeaf(Node node, Maximum max_sum_ref,
int curr_sum)
{
if (node == null) {
return;
}
// Update current sum to hold sum of nodes on
// path from root to this node
curr_sum = curr_sum + node.data;
// If this is a leaf node and path to this node
// has maximum sum so far, the n make this node
// target_leaf
if (node.left == null && node.right == null) {
if (curr_sum > max_sum_ref.max_no) {
max_sum_ref.max_no = curr_sum;
target_leaf = node;
}
}
// If this is not a leaf node, then recur down
// to find the target_leaf
getTargetLeaf(node.left, max_sum_ref, curr_sum);
getTargetLeaf(node.right, max_sum_ref, curr_sum);
}
// Returns the maximum sum and prints the nodes on
// max sum path
public virtual int maxSumPath()
{
// base case
if (root == null) {
return 0;
}
// find the target leaf and maximum sum
getTargetLeaf(root, max, 0);
// print the path from root to the target leaf
printPath(root, target_leaf);
return max.max_no; // return maximum sum
}
// driver function to test the above functions
public static void Main(string[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(-2);
tree.root.right = new Node(7);
tree.root.left.left = new Node(8);
tree.root.left.right = new Node(-4);
Console.WriteLine("Following are the nodes "
+ "on maximum sum path");
int sum = tree.maxSumPath();
Console.WriteLine("");
Console.WriteLine("Sum of nodes is : " + sum);
}
}
// This code is contributed by Shrikant13
输出:
Following are the nodes on the maximum sum path
7 10
Sum of the nodes is 17
时间复杂度:上述解决方案的时间复杂度为 O(n),因为它涉及两次树遍历。