📜  在二叉树中找到最大垂直和

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

在二叉树中找到最大垂直和

给定一棵二叉树,求二叉树的最大垂直层次和。

例子:

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。

Input : 
                3
              /  \
             4    6
           /  \  /  \
         -1   -2 5   10
                  \
                   8  

Output : 14
Vertical level having nodes 6 and 8 has maximum
vertical sum 14. 

Input :
                1
              /  \
             5    8
           /  \    \
          2   -6    3
           \       /
           -1     -4
             \
              9

Output : 4 
推荐:请先在 IDE 上尝试您的方法,然后再查看解决方案。

一个简单的解决方案是首先找到从最小垂直水平到最大垂直水平的每个水平的垂直水平总和。找到一个垂直级别的总和需要 O(n) 时间。在最坏情况下,此解决方案的时间复杂度为 O(n^2)。



一个有效的解决方案是对给定的二叉树进行层序遍历,并在遍历的同时更新每一层的垂直层和。在找到每个级别的垂直总和后,从这些值中找到最大的垂直总和。

下面是上述方法的实现:

C++
// C++ program to find maximum vertical
// sum in binary tree.
#include 
using namespace std;
 
// A Binary Tree Node
struct Node {
    int data;
    struct Node *left, *right;
};
 
// A utility function to create a new
// Binary Tree Node
struct Node* newNode(int item)
{
    struct Node* temp = (struct Node*)malloc(sizeof(struct Node));
    temp->data = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// Function to find maximum vertical sum
// in binary tree.
int maxVerticalSum(Node* root)
{
    if (root == NULL) {
        return 0;
    }
 
    // To store sum of each vertical level.
    unordered_map verSum;
 
    // To store maximum vertical level sum.
    int maxSum = INT_MIN;
 
    // To store vertical level of current node.
    int currLev;
 
    // Queue to perform level order traversal.
    // Each element of queue is a pair of node
    // and its vertical level.
    queue > q;
    q.push({ root, 0 });
 
    while (!q.empty()) {
 
        // Extract node at front of queue
        // and its vertical level.
        root = q.front().first;
        currLev = q.front().second;
        q.pop();
 
        // Update vertical level sum of
        // vertical level to which
        // current node belongs to.
        verSum[currLev] += root->data;
 
        if (root->left)
            q.push({ root->left, currLev - 1 });
 
        if (root->right)
            q.push({ root->right, currLev + 1 });
    }
 
    // Find maximum vertical level sum.
    for (auto it : verSum)
        maxSum = max(maxSum, it.second);
    
    return maxSum;
}
 
// Driver Program to test above functions
int main()
{
    /*
                3
              /  \
             4    6
           /  \  /  \
         -1   -2 5   10
                  \
                   8 
    */
 
    struct Node* root = newNode(3);
    root->left = newNode(4);
    root->right = newNode(6);
    root->left->left = newNode(-1);
    root->left->right = newNode(-2);
    root->right->left = newNode(5);
    root->right->right = newNode(10);
    root->right->left->right = newNode(8);
 
    cout << maxVerticalSum(root);
    return 0;
}


Python3
# Python3 program to find maximum
# vertical sum in binary tree.
from sys import maxsize
from collections import deque
 
INT_MIN = -maxsize
 
class Node:
     
    def __init__(self, data):
         
        self.data = data
        self.left = None
        self.right = None
 
# Function to find maximum vertical sum
# in binary tree.
def maxVerticalSum(root: Node) -> int:
     
    if (root is None):
        return 0
 
    # To store sum of each vertical level.
    verSum = dict()
 
    # To store maximum vertical level sum.
    maxSum = INT_MIN
 
    # To store vertical level of current node.
    currLev = 0
 
    # Queue to perform level order traversal.
    # Each element of queue is a pair of node
    # and its vertical level.
    q = deque()
    q.append([root, 0])
 
    while (q):
 
        # Extract node at front of queue
        # and its vertical level.
        root = q[0][0]
        currLev = q[0][1]
        q.popleft()
 
        # Update vertical level sum of
        # vertical level to which
        # current node belongs to.
        if currLev not in verSum:
            verSum[currLev] = 0
             
        verSum[currLev] += root.data
 
        if (root.left):
            q.append([root.left, currLev - 1])
 
        if (root.right):
            q.append([root.right, currLev + 1])
 
    # Find maximum vertical level sum.
    for it in verSum:
        maxSum = max([maxSum, verSum[it]])
 
    return maxSum
 
# Driver code
if __name__ == "__main__":
     
    '''
                3
              /  \
             4    6
           /  \  /  \
         -1   -2 5   10
                  \
                   8 
    '''
 
    root = Node(3)
    root.left = Node(4)
    root.right = Node(6)
    root.left.left = Node(-1)
    root.left.right = Node(-2)
    root.right.left = Node(5)
    root.right.right = Node(10)
    root.right.left.right = Node(8)
 
    print(maxVerticalSum(root))
 
# This code is contributed by sanjeev2552


Javascript


输出:
14

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