从根到叶节点的最长路径上的节点总和
给定一棵包含n 个节点的二叉树。问题是找到从根到叶节点的最长路径上所有节点的总和。如果两条或更多条路径竞争最长路径,则考虑具有最大节点和的路径。
例子:
Input : Binary tree:
4
/ \
2 5
/ \ / \
7 1 2 3
/
6
Output : 13
4
/ \
2 5
/ \ / \
7 1 2 3
/
6
The highlighted nodes (4, 2, 1, 6) above are
part of the longest root to leaf path having
sum = (4 + 2 + 1 + 6) = 13
方法:递归地找到每个根到叶路径的节点的长度和总和,并相应地更新最大总和。
算法:
sumOfLongRootToLeafPath(root, sum, len, maxLen, maxSum)
if root == NULL
if maxLen < len
maxLen = len
maxSum = sum
else if maxLen == len && maxSum is less than sum
maxSum = sum
return
sumOfLongRootToLeafPath(root-left, sum + root-data,
len + 1, maxLen, maxSum)
sumOfLongRootToLeafPath(root-right, sum + root-data,
len + 1, maxLen, maxSum)
sumOfLongRootToLeafPathUtil(root)
if (root == NULL)
return 0
Declare maxSum = Minimum Integer
Declare maxLen = 0
sumOfLongRootToLeafPath(root, 0, 0, maxLen, maxSum)
return maxSum
C++
// C++ implementation to find the sum of nodes
// on the longest path from root to leaf node
#include
using namespace std;
// Node of a binary tree
struct Node {
int data;
Node* left, *right;
};
// function to get a new node
Node* getNode(int data)
{
// allocate memory for the node
Node* newNode = (Node*)malloc(sizeof(Node));
// put in the data
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
// function to find the sum of nodes on the
// longest path from root to leaf node
void sumOfLongRootToLeafPath(Node* root, int sum,
int len, int& maxLen, int& maxSum)
{
// if true, then we have traversed a
// root to leaf path
if (!root) {
// update maximum length and maximum sum
// according to the given conditions
if (maxLen < len) {
maxLen = len;
maxSum = sum;
} else if (maxLen == len && maxSum < sum)
maxSum = sum;
return;
}
// recur for left subtree
sumOfLongRootToLeafPath(root->left, sum + root->data,
len + 1, maxLen, maxSum);
// recur for right subtree
sumOfLongRootToLeafPath(root->right, sum + root->data,
len + 1, maxLen, maxSum);
}
// utility function to find the sum of nodes on
// the longest path from root to leaf node
int sumOfLongRootToLeafPathUtil(Node* root)
{
// if tree is NULL, then sum is 0
if (!root)
return 0;
int maxSum = INT_MIN, maxLen = 0;
// finding the maximum sum 'maxSum' for the
// maximum length root to leaf path
sumOfLongRootToLeafPath(root, 0, 0, maxLen, maxSum);
// required maximum sum
return maxSum;
}
// Driver program to test above
int main()
{
// binary tree formation
Node* root = getNode(4); /* 4 */
root->left = getNode(2); /* / \ */
root->right = getNode(5); /* 2 5 */
root->left->left = getNode(7); /* / \ / \ */
root->left->right = getNode(1); /* 7 1 2 3 */
root->right->left = getNode(2); /* / */
root->right->right = getNode(3); /* 6 */
root->left->right->left = getNode(6);
cout << "Sum = "
<< sumOfLongRootToLeafPathUtil(root);
return 0;
}
Java
// Java implementation to find the sum of nodes
// on the longest path from root to leaf node
public class GFG
{
// Node of a binary tree
static class Node {
int data;
Node left, right;
Node(int data){
this.data = data;
left = null;
right = null;
}
}
static int maxLen;
static int maxSum;
// function to find the sum of nodes on the
// longest path from root to leaf node
static void sumOfLongRootToLeafPath(Node root, int sum,
int len)
{
// if true, then we have traversed a
// root to leaf path
if (root == null) {
// update maximum length and maximum sum
// according to the given conditions
if (maxLen < len) {
maxLen = len;
maxSum = sum;
} else if (maxLen == len && maxSum < sum)
maxSum = sum;
return;
}
// recur for left subtree
sumOfLongRootToLeafPath(root.left, sum + root.data,
len + 1);
sumOfLongRootToLeafPath(root.right, sum + root.data,
len + 1);
}
// utility function to find the sum of nodes on
// the longest path from root to leaf node
static int sumOfLongRootToLeafPathUtil(Node root)
{
// if tree is NULL, then sum is 0
if (root == null)
return 0;
maxSum = Integer.MIN_VALUE;
maxLen = 0;
// finding the maximum sum 'maxSum' for the
// maximum length root to leaf path
sumOfLongRootToLeafPath(root, 0, 0);
// required maximum sum
return maxSum;
}
// Driver program to test above
public static void main(String args[])
{
// binary tree formation
Node root = new Node(4); /* 4 */
root.left = new Node(2); /* / \ */
root.right = new Node(5); /* 2 5 */
root.left.left = new Node(7); /* / \ / \ */
root.left.right = new Node(1); /* 7 1 2 3 */
root.right.left = new Node(2); /* / */
root.right.right = new Node(3); /* 6 */
root.left.right.left = new Node(6);
System.out.println( "Sum = "
+ sumOfLongRootToLeafPathUtil(root));
}
}
// This code is contributed by Sumit Ghosh
Python3
# Python3 implementation to find the
# Sum of nodes on the longest path
# from root to leaf nodes
# function to get a new node
class getNode:
def __init__(self, data):
# put in the data
self.data = data
self.left = self.right = None
# function to find the Sum of nodes on the
# longest path from root to leaf node
def SumOfLongRootToLeafPath(root, Sum, Len,
maxLen, maxSum):
# if true, then we have traversed a
# root to leaf path
if (not root):
# update maximum Length and maximum Sum
# according to the given conditions
if (maxLen[0] < Len):
maxLen[0] = Len
maxSum[0] = Sum
else if (maxLen[0]== Len and
maxSum[0] < Sum):
maxSum[0] = Sum
return
# recur for left subtree
SumOfLongRootToLeafPath(root.left, Sum + root.data,
Len + 1, maxLen, maxSum)
# recur for right subtree
SumOfLongRootToLeafPath(root.right, Sum + root.data,
Len + 1, maxLen, maxSum)
# utility function to find the Sum of nodes on
# the longest path from root to leaf node
def SumOfLongRootToLeafPathUtil(root):
# if tree is NULL, then Sum is 0
if (not root):
return 0
maxSum = [-999999999999]
maxLen = [0]
# finding the maximum Sum 'maxSum' for
# the maximum Length root to leaf path
SumOfLongRootToLeafPath(root, 0, 0,
maxLen, maxSum)
# required maximum Sum
return maxSum[0]
# Driver Code
if __name__ == '__main__':
# binary tree formation
root = getNode(4) # 4
root.left = getNode(2) # / \
root.right = getNode(5) # 2 5
root.left.left = getNode(7) # / \ / \
root.left.right = getNode(1) # 7 1 2 3
root.right.left = getNode(2) # /
root.right.right = getNode(3) # 6
root.left.right.left = getNode(6)
print("Sum = ", SumOfLongRootToLeafPathUtil(root))
# This code is contributed by PranchalK
C#
using System;
// c# implementation to find the sum of nodes
// on the longest path from root to leaf node
public class GFG
{
// Node of a binary tree
public class Node
{
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
public static int maxLen;
public static int maxSum;
// function to find the sum of nodes on the
// longest path from root to leaf node
public static void sumOfLongRootToLeafPath(Node root, int sum, int len)
{
// if true, then we have traversed a
// root to leaf path
if (root == null)
{
// update maximum length and maximum sum
// according to the given conditions
if (maxLen < len)
{
maxLen = len;
maxSum = sum;
}
else if (maxLen == len && maxSum < sum)
{
maxSum = sum;
}
return;
}
// recur for left subtree
sumOfLongRootToLeafPath(root.left, sum + root.data, len + 1);
sumOfLongRootToLeafPath(root.right, sum + root.data, len + 1);
}
// utility function to find the sum of nodes on
// the longest path from root to leaf node
public static int sumOfLongRootToLeafPathUtil(Node root)
{
// if tree is NULL, then sum is 0
if (root == null)
{
return 0;
}
maxSum = int.MinValue;
maxLen = 0;
// finding the maximum sum 'maxSum' for the
// maximum length root to leaf path
sumOfLongRootToLeafPath(root, 0, 0);
// required maximum sum
return maxSum;
}
// Driver program to test above
public static void Main(string[] args)
{
// binary tree formation
Node root = new Node(4); // 4
root.left = new Node(2); // / \
root.right = new Node(5); // 2 5
root.left.left = new Node(7); // / \ / \
root.left.right = new Node(1); // 7 1 2 3
root.right.left = new Node(2); // /
root.right.right = new Node(3); // 6
root.left.right.left = new Node(6);
Console.WriteLine("Sum = " + sumOfLongRootToLeafPathUtil(root));
}
}
// This code is contributed by Shrikant13
Javascript
C++
#include
using namespace std;
//Building a tree node having left and right pointers set to null initially
struct Node
{
Node* left;
Node* right;
int data;
//constructor to set the data of the newly created tree node
Node(int element){
data = element;
this->left = nullptr;
this->right = nullptr;
}
};
int longestPathLeaf(Node* root){
/* structure to store current Node,it's level and sum in the path*/
struct Element{
Node* data;
int level;
int sum;
};
/*
maxSumLevel stores maximum sum so far in the path
maxLevel stores maximum level so far
*/
int maxSumLevel = root->data,maxLevel = 0;
/* queue to implement level order traversal */
list que;
Element e;
/* Each element variable stores the current Node, it's level, sum in the path */
e.data = root;
e.level = 0;
e.sum = root->data;
/* push the root element*/
que.push_back(e);
/* do level order traversal on the tree*/
while(!que.empty()){
Element front = que.front();
Node* curr = front.data;
que.pop_front();
/* if the level of current front element is greater than the maxLevel so far then update maxSum*/
if(front.level > maxLevel){
maxSumLevel = front.sum;
maxLevel = front.level;
}
/* if another path competes then update if the sum is greater than the previous path of same height*/
else if(front.level == maxLevel && front.sum > maxSumLevel)
maxSumLevel = front.sum;
/* push the left element if exists*/
if(curr->left){
e.data = curr->left;
e.sum = e.data->data;
e.sum += front.sum;
e.level = front.level+1;
que.push_back(e);
}
/*push the right element if exists*/
if(curr->right){
e.data = curr->right;
e.sum = e.data->data;
e.sum += front.sum;
e.level = front.level+1;
que.push_back(e);
}
}
/*return the answer*/
return maxSumLevel;
}
//Helper function
int main() {
Node* root = new Node(4);
root->left = new Node(2);
root->right = new Node(5);
root->left->left = new Node(7);
root->left->right = new Node(1);
root->right->left = new Node(2);
root->right->right = new Node(3);
root->left->right->left = new Node(6);
cout << longestPathLeaf(root) << "\n";
return 0;
}
输出
Sum = 13
时间复杂度: O(n)
另一种方法:使用水平顺序遍历
- 在路径中创建一个包含当前节点、级别和总和的结构。
- 将级别为 0 的根元素推入并求和作为根的数据。
- 如果需要,弹出前面的元素并更新最大级别总和和最大级别。
- 如果存在,则推送左右节点。
- 对树中的所有节点执行相同的操作。
C++
#include
using namespace std;
//Building a tree node having left and right pointers set to null initially
struct Node
{
Node* left;
Node* right;
int data;
//constructor to set the data of the newly created tree node
Node(int element){
data = element;
this->left = nullptr;
this->right = nullptr;
}
};
int longestPathLeaf(Node* root){
/* structure to store current Node,it's level and sum in the path*/
struct Element{
Node* data;
int level;
int sum;
};
/*
maxSumLevel stores maximum sum so far in the path
maxLevel stores maximum level so far
*/
int maxSumLevel = root->data,maxLevel = 0;
/* queue to implement level order traversal */
list que;
Element e;
/* Each element variable stores the current Node, it's level, sum in the path */
e.data = root;
e.level = 0;
e.sum = root->data;
/* push the root element*/
que.push_back(e);
/* do level order traversal on the tree*/
while(!que.empty()){
Element front = que.front();
Node* curr = front.data;
que.pop_front();
/* if the level of current front element is greater than the maxLevel so far then update maxSum*/
if(front.level > maxLevel){
maxSumLevel = front.sum;
maxLevel = front.level;
}
/* if another path competes then update if the sum is greater than the previous path of same height*/
else if(front.level == maxLevel && front.sum > maxSumLevel)
maxSumLevel = front.sum;
/* push the left element if exists*/
if(curr->left){
e.data = curr->left;
e.sum = e.data->data;
e.sum += front.sum;
e.level = front.level+1;
que.push_back(e);
}
/*push the right element if exists*/
if(curr->right){
e.data = curr->right;
e.sum = e.data->data;
e.sum += front.sum;
e.level = front.level+1;
que.push_back(e);
}
}
/*return the answer*/
return maxSumLevel;
}
//Helper function
int main() {
Node* root = new Node(4);
root->left = new Node(2);
root->right = new Node(5);
root->left->left = new Node(7);
root->left->right = new Node(1);
root->right->left = new Node(2);
root->right->right = new Node(3);
root->left->right->left = new Node(6);
cout << longestPathLeaf(root) << "\n";
return 0;
}
输出
13
时间复杂度: O(N)
辅助空间: O(N)
文殊克里希纳供稿