Sum of nodes in bottom view of Binary Tree
Given a binary tree, the task is to return the sum of nodes in the bottom view of the given Binary Tree. The bottom view of a binary tree is the set of nodes visible when the tree is viewed from the bottom.
Note: If there are multiple bottom-most nodes for a horizontal distance from the root, then the latter one in the level traversal is considered.
Examples:
Example1: Sum of nodes in bottom view of Below Binary Tree [5, 10, 14, 4, 25] is 58 as 3 is not considered in the bottom view as 4 is present at same horizontal distance, so latter one is considered.
![]()
Example2: Sum of nodes in bottom view of Below Binary Tree [4, 2, 5, 3, 6] is 20.
Table of Content
[Expected Approach – 1] Using Level-Order Traversal – O(nlogn) Time and O(n) Space
The idea is to perform a level-order traversal while tracking each node’s horizontal distance (HD) from the root, similar to the bottom view. Starting with the root at HD equals 0, left children have HD – 1 and right children have HD + 1. We use a queue to process nodes level by level, updating a map with the sum of node values at each corresponding HD. Each node’s value is added to the sum of its HD to represent the cumulative sum of nodes at that level. By tracking the minimum and maximum HDs during traversal, we know the full range of HDs. After traversal, we extract the sum of nodes from the map in order of their HDs, which gives us the total sum for the bottom view of the tree.
Below is the implementation of the above approach:
// C++ code to find the sum of the bottom view
// using level-order traversal
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// Function to return the sum of the bottom view
// of the binary tree
int bottomViewSum(Node *root) {
if (!root) return 0;
// Map to store the last node at each
// horizontal distance (HD)
map<int, int> hdMap;
// Queue to store nodes and their HD
queue<pair<Node*, int>> q;
// Start level order traversal
// with root at HD 0
q.push({root, 0});
while (!q.empty()) {
// Get current node and its HD
Node *curr = q.front().first;
int hd = q.front().second;
q.pop();
// Update the map with the
// current node's data
hdMap[hd] = curr->data;
// Traverse the left subtree, HD - 1
if (curr->left) {
q.push({curr->left, hd - 1});
}
// Traverse the right subtree, HD + 1
if (curr->right) {
q.push({curr->right, hd + 1});
}
}
// Calculate the sum of the
// bottom view nodes
int sum = 0;
for (auto it : hdMap) {
sum += it.second;
}
return sum;
}
int main() {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node *root = new Node(20);
root->left = new Node(8);
root->right = new Node(22);
root->left->left = new Node(5);
root->left->right = new Node(3);
root->left->right->left = new Node(10);
root->left->right->right = new Node(14);
root->right->right = new Node(25);
int sum = bottomViewSum(root);
cout << sum << endl;
return 0;
}
// Java code to find the sum of the bottom view
// using level-order traversal
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function to return the sum of the bottom
// view of the binary tree
static int bottomViewSum(Node root) {
if (root == null) return 0;
// Map to store the last node at each
// horizontal distance (HD)
Map<Integer, Integer> hdMap = new TreeMap<>();
// Queue to store nodes and their
// horizontal distance
Queue<Pair> q = new LinkedList<>();
// Start level order traversal
// with root at HD 0
q.add(new Pair(root, 0));
while (!q.isEmpty()) {
// Get current node and its HD
Node curr = q.peek().node;
int hd = q.peek().hd;
q.poll();
// Update the map with the
// current node's data
hdMap.put(hd, curr.data);
// Traverse the left subtree, HD - 1
if (curr.left != null) {
q.add(new Pair(curr.left, hd - 1));
}
// Traverse the right subtree, HD + 1
if (curr.right != null) {
q.add(new Pair(curr.right, hd + 1));
}
}
// Calculate the sum of the
// bottom view nodes
int sum = 0;
// Iterate through the map in sorted HD
// order and sum values
for (int value : hdMap.values()) {
sum += value;
}
return sum;
}
static class Pair {
Node node;
int hd;
Pair(Node node, int hd) {
this.node = node;
this.hd = hd;
}
}
public static void main(String[] args) {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
int sum = bottomViewSum(root);
System.out.println(sum);
}
}
# Python code to find the sum of the bottom view
# using level-order traversal
from collections import deque
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to return the sum of
# the bottom view of the binary tree
def bottomViewSum(root):
if not root:
return 0
# Dictionary to store the last node at
# each horizontal distance (HD)
hd_map = {}
# Queue to store nodes and their horizontal
# distance
q = deque([(root, 0)])
while q:
# Get current node and its HD
curr, hd = q.popleft()
# Update the map with the current node's data
hd_map[hd] = curr.data
# Traverse the left subtree, HD - 1
if curr.left:
q.append((curr.left, hd - 1))
# Traverse the right subtree, HD + 1
if curr.right:
q.append((curr.right, hd + 1))
# Calculate the sum of the bottom
# view nodes
sum_bottom_view = sum(hd_map[hd] for hd in hd_map)
return sum_bottom_view
if __name__ == "__main__":
# Representation of the input tree:
# 20
# / \
# 8 22
# / \ \
# 5 3 25
# / \
# 10 14
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(5)
root.left.right = Node(3)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
root.right.right = Node(25)
sum_result = bottomViewSum(root)
print(sum_result)
// C# code to find the sum of the bottom view
// using level-order traversal
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function to return the sum of the bottom
// view of the tree
static int bottomViewSum(Node root) {
if (root == null) return 0;
// Dictionary to store last node at
// each horizontal distance (HD)
SortedDictionary<int, int> hdMap =
new SortedDictionary<int, int>();
// Queue to store nodes and their
// horizontal distance
Queue<Tuple<Node, int>> q =
new Queue<Tuple<Node, int>>();
// Start level order traversal
// with root at HD 0
q.Enqueue(new Tuple<Node, int>(root, 0));
while (q.Count > 0) {
// Get current node and its
// horizontal distance
var currPair = q.Dequeue();
Node curr = currPair.Item1;
int hd = currPair.Item2;
// Update the map with the
// current node's data
hdMap[hd] = curr.data;
// Traverse the left subtree, HD - 1
if (curr.left != null) {
q.Enqueue(new Tuple<Node,
int>(curr.left, hd - 1));
}
// Traverse the right subtree, HD + 1
if (curr.right != null) {
q.Enqueue(new Tuple<Node,
int>(curr.right, hd + 1));
}
}
// Calculate the sum of the
// bottom view nodes
int sumBottomView = 0;
foreach (var entry in hdMap) {
sumBottomView += entry.Value;
}
return sumBottomView;
}
static void Main(string[] args) {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
int sumResult = bottomViewSum(root);
Console.WriteLine(sumResult);
}
}
// JavaScript code to find the sum of the bottom view
// using level-order traversal
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Function to return the sum of the bottom
// view of the binary tree
function bottomViewSum(root) {
if (!root) return 0;
// Map to store last node at each
// horizontal distance (HD)
const hdMap = new Map();
// Queue to store nodes and their
// horizontal distance
const queue = [];
// Start level order traversal
// with root at HD 0
queue.push([root, 0]);
while (queue.length > 0) {
// Get current node and its HD
const [curr, hd] = queue.shift();
// Update the map with the
// current node's data
hdMap.set(hd, curr.data);
// Traverse the left subtree, HD - 1
if (curr.left) {
queue.push([curr.left, hd - 1]);
}
// Traverse the right subtree, HD + 1
if (curr.right) {
queue.push([curr.right, hd + 1]);
}
}
// Calculate the sum of the
// bottom view nodes
let sumBottomView = 0;
for (const value of hdMap.values()) {
sumBottomView += value;
}
return sumBottomView;
}
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
const root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
const sumResult = bottomViewSum(root);
console.log(sumResult);
Output
57
[Expected Approach – 2] Using Depth-First Search – O(nlogn) Time and O(n) Space
Create a map where the key is the horizontal distance, and the value is a pair (sum, height) where sum is the cumulative sum of the node values at that horizontal distance, and height is the height of the last node seen at that distance. Perform a pre-order traversal of the tree. If the current node at a horizontal distance of h is the first we’ve seen, insert it into the map. Otherwise, compare the node’s height with the existing one in the map, and if the new node’s height is greater, update the sum for that horizontal distance.
Below is the implementation of above approach:
// C++ code to find the sum of the bottom view
// using depth-first search (DFS)
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// Helper function to perform DFS and
// update the bottom view
void dfs(Node* root, int hd, int depth,
map<int, pair<int, int>>& hdMap) {
if (!root) return;
// If this horizontal distance is
// being visited for the first time or
// we're at a deeper level, update it
if (hdMap.find(hd) == hdMap.end()
|| depth >= hdMap[hd].second) {
hdMap[hd] = {root->data, depth};
}
// Traverse the left subtree with
// HD - 1 and increased depth
dfs(root->left, hd - 1, depth + 1, hdMap);
// Traverse the right subtree with
// HD + 1 and increased depth
dfs(root->right, hd + 1, depth + 1, hdMap);
}
// Function to return the sum of the bottom view
// of the binary tree using DFS
int bottomViewSum(Node *root) {
if (!root) return 0;
// Map to store the last node's data and its depth
// at each horizontal distance (HD)
map<int, pair<int, int>> hdMap;
// Start DFS with root at HD 0 and depth 0
dfs(root, 0, 0, hdMap);
// Calculate the sum of the bottom view nodes
int sumBottomView = 0;
for (auto it : hdMap) {
sumBottomView += it.second.first;
}
return sumBottomView;
}
int main() {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node *root = new Node(20);
root->left = new Node(8);
root->right = new Node(22);
root->left->left = new Node(5);
root->left->right = new Node(3);
root->left->right->left = new Node(10);
root->left->right->right = new Node(14);
root->right->right = new Node(25);
int sumResult = bottomViewSum(root);
cout << sumResult << endl;
return 0;
}
// Java code to find the sum of the bottom view
// using depth-first search (DFS)
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Helper function to perform DFS and update
// the bottom view
static void dfs(Node root, int hd, int depth,
Map<Integer, Pair> hdMap) {
if (root == null) return;
// If this horizontal distance is
// being visited for the first time or
// we're at a deeper level, update it
if (!hdMap.containsKey(hd)
|| depth >= hdMap.get(hd).depth) {
hdMap.put(hd, new Pair(root.data, depth));
}
// Traverse the left subtree with
// HD - 1 and increased depth
dfs(root.left, hd - 1, depth + 1, hdMap);
// Traverse the right subtree
// with HD + 1 and increased depth
dfs(root.right, hd + 1, depth + 1, hdMap);
}
// Function to return the sum of the bottom view
// of the binary tree using DFS
static int bottomViewSum(Node root) {
if (root == null) return 0;
// Map to store the last node's data and its depth
// at each horizontal distance (HD)
Map<Integer, Pair> hdMap = new TreeMap<>();
// Start DFS with root at HD 0 and depth 0
dfs(root, 0, 0, hdMap);
// Calculate the sum of the bottom view nodes
int sumBottomView = 0;
for (Pair value : hdMap.values()) {
sumBottomView += value.data;
}
return sumBottomView;
}
// Pair class to store node
// data and depth
static class Pair {
int data, depth;
Pair(int data, int depth) {
this.data = data;
this.depth = depth;
}
}
public static void main(String[] args) {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
int sumResult = bottomViewSum(root);
System.out.println(sumResult);
}
}
# Python code to find the sum of the bottom view
# using depth-first search (DFS)
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Helper function to perform DFS and update
# the bottom view
def dfs(root, hd, depth, hd_map):
if not root:
return
# If this horizontal distance is being
# visited for the first time or
# we're at a deeper level, update it
if hd not in hd_map or depth >= hd_map[hd][1]:
hd_map[hd] = (root.data, depth)
# Traverse the left subtree with HD - 1
# and increased depth
dfs(root.left, hd - 1, depth + 1, hd_map)
# Traverse the right subtree with HD + 1
# and increased depth
dfs(root.right, hd + 1, depth + 1, hd_map)
# Function to return the sum of the bottom view
# of the binary tree using DFS
def bottomViewSum(root):
if not root:
return 0
# Dictionary to store the last node's data
# and its depth at each horizontal distance (HD)
hd_map = {}
# Start DFS with root at HD 0 and depth 0
dfs(root, 0, 0, hd_map)
# Calculate the sum of the bottom view nodes
sum_bottom_view = sum(hd_map[hd][0] \
for hd in sorted(hd_map.keys()))
return sum_bottom_view
if __name__ == "__main__":
# Representation of the input tree:
# 20
# / \
# 8 22
# / \ \
# 5 3 25
# / \
# 10 14
root = Node(20)
root.left = Node(8)
root.right = Node(22)
root.left.left = Node(5)
root.left.right = Node(3)
root.left.right.left = Node(10)
root.left.right.right = Node(14)
root.right.right = Node(25)
sum_result = bottomViewSum(root)
print(sum_result)
// C# code to find the sum of the bottom view
// using depth-first search (DFS)
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Helper function to perform DFS and update
// the bottom view
static void DFS(Node root, int hd, int depth,
Dictionary<int, (int, int)> hdMap) {
if (root == null) return;
// If this horizontal distance is being visited
// for the first time or we're at a deeper
// level, update it
if (!hdMap.ContainsKey(hd)
|| depth >= hdMap[hd].Item2) {
hdMap[hd] = (root.data, depth);
}
// Traverse the left subtree with HD - 1
// and increased depth
DFS(root.left, hd - 1, depth + 1, hdMap);
// Traverse the right subtree with HD + 1
// and increased depth
DFS(root.right, hd + 1, depth + 1, hdMap);
}
// Function to return the sum of the bottom view
// of the binary tree using DFS
static int bottomViewSum(Node root) {
if (root == null) return 0;
// Dictionary to store the last node's data
// and its depth at each horizontal distance (HD)
var hdMap = new Dictionary<int, (int, int)>();
// Start DFS with root at HD 0 and depth 0
DFS(root, 0, 0, hdMap);
// Calculate the sum of the bottom view nodes
int sumBottomView = 0;
foreach (var key in hdMap.Keys) {
sumBottomView += hdMap[key].Item1;
}
return sumBottomView;
}
static void Main() {
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
Node root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
int sumResult = bottomViewSum(root);
Console.WriteLine(sumResult);
}
}
// JavaScript code to find the sum of the bottom view
// using depth-first search (DFS)
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// Helper function to perform DFS and
// update the bottom view
function dfs(root, hd, depth, hdMap) {
if (!root) return;
// If this horizontal distance is being
// visited for the first time
// or we're at a deeper level, update it
if (!(hd in hdMap) || depth >= hdMap[hd][1]) {
hdMap[hd] = [root.data, depth];
}
// Traverse the left subtree with HD - 1
// and increased depth
dfs(root.left, hd - 1, depth + 1, hdMap);
// Traverse the right subtree with
// HD + 1 and increased depth
dfs(root.right, hd + 1, depth + 1, hdMap);
}
// Function to return the sum of the bottom view of
// the binary tree using DFS
function bottomViewSum(root) {
if (!root) return 0;
// Map to store the last node's data and its
// depth at each horizontal distance (HD)
const hdMap = {};
// Start DFS with root at HD 0 and depth 0
dfs(root, 0, 0, hdMap);
// Calculate the sum of the bottom view nodes
let sumBottomView = 0;
// Get the keys (horizontal distances) in sorted order
const sortedKeys
= Object.keys(hdMap).map(Number).sort((a, b) => a - b);
// Iterate through the map in sorted HD order
for (const key of sortedKeys) {
sumBottomView += hdMap[key][0];
}
return sumBottomView;
}
// Representation of the input tree:
// 20
// / \
// 8 22
// / \ \
// 5 3 25
// / \
// 10 14
const root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(5);
root.left.right = new Node(3);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);
root.right.right = new Node(25);
const sumResult = bottomViewSum(root);
console.log(sumResult);
Output
57