Given a binary tree, return the sum of values of its deepest leaves.
Example 1:
Input: root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
Output: 15
Constraints:
The number of nodes in the tree is between 1 and 10^4.
The value of nodes is between 1 and 100.
hint1:Traverse the tree to find the max depth.
hint2:Traverse the tree again to compute the sum required.
answer one:
Explanation
pre are nodes in the previous level.
q are node in the current level.
When current level are empty,
the previous level are the deepest leaves.
Complexity
Time O(N)
Space O(N)
public int deepestLeavesSum(TreeNode root) {
int res = 0, i;
LinkedList<TreeNode> q = new LinkedList<TreeNode>();
q.add(root);
while (!q.isEmpty()) {
for (i = q.size() - 1, res = 0; i >= 0; --i) {
TreeNode node = q.poll();
res += node.val;
if (node.right != null) q.add(node.right);
if (node.left != null) q.add(node.left);
}
}
return res;
}
answer tow:
Similar idea in Java:
public int deepestLeavesSum(TreeNode root) {
Queue<TreeNode> q=new LinkedList<>();
int sum=0;
q.offer(root);
while(!q.isEmpty()) {
int size=q.size();
sum=0;
for(int i=0;i<size;i++) {
TreeNode cur=q.poll();
sum+=cur.val;
if(cur.left!=null) q.offer(cur.left);
if(cur.right!=null) q.offer(cur.right);
}
}
return sum;
}
answer three:
DFS solution using map that seems slightly faster:
public int deepestLeavesSum(TreeNode root) {
Map<Integer, Integer> map = new HashMap();
helper(root, map, 0);
int maxD = 0;
for(int d : map.keySet()){
maxD = Math.max(d, maxD);
}
return map.get(maxD);
}
private void helper(TreeNode root, Map<Integer, Integer> map, int depth){
if(root == null) return;
if(root.left != null) helper(root.left, map, depth + 1);
if(root.right != null) helper(root.right, map, depth + 1);
if(root.left == null && root.right == null) map.put(depth, map.getOrDefault(depth, 0) + root.val);
answer four:
Complexity
Time: O(N), N is the number of nodes in the tree
Space: O(N/2), size of the largest level
Nice trick iterating up to size and avoiding the need for a second queue.
Thanks for sharing.
I think in this case we can go for a simple recursion. Such code would be much easier to write at the contest time.
class Solution {
public int deepestLeavesSum(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int sum = 0;
while (!q.isEmpty()) {
int size = q.size();
sum = 0; // Reset for calculating the sum of elements of the next level
while (size-- > 0) {
TreeNode top = q.poll();
sum += top.val;
if (top.left != null) q.offer(top.left);
if (top.right != null) q.offer(top.right);
}
}
return sum;
}
}
answer five:
[Java] 1ms DFS single traversal - O(N)
Explanation
Do a preorder traversal of the tree.
Basically when you approach a leaf node, do one of the following
If the current leaf node depth is greater than the maximum leaf depth found till now, set maximum depth as current leaf depth and initialize the sum of deepest leaf nodes as the value of the current leaf node.
If the current leaf node depth is less than the maximum leaf depth found till now, dont do anything.
If the current leaf node depth is equal to the maximum leaf depth found till now, increase the sum of the deepest leaf nodes by the value of the current leaf node.
This solution involves just a single traversal of the tree.
Complexity
Time O(N)
Space O(N)
class Solution {
public int deepestLeavesSum(TreeNode root) {
int[] maxDepth = new int[1];
int[] sumOfDeepestLeaves = new int[1];
findDepth(root, maxDepth, sumOfDeepestLeaves, 1);
return sumOfDeepestLeaves[0];
}
public void findDepth(TreeNode root, int[] maxDepth, int[] sumOfDeepestLeaves,
int currDepth) {
if(root == null) {
return;
}
if(root.left == null && root.right == null) {
/** If depth of the current leaf is equal to existing maximum depth,
add the value of this leaf to the existing sum of deepest leaves. */
if(maxDepth[0] == currDepth) {
sumOfDeepestLeaves[0] += root.val;
return;
/** If depth of the current leaf is less than the existing maximum depth,
dont change the existing sum of deepest leaves and return. */
} else if(currDepth < maxDepth[0]) {
return;
/** If depth of the current leaf is greater than the existing maximum depth,
set max depth to current depth and also initialize the sum of deepest leaves
as the current node val */
} else {
sumOfDeepestLeaves[0] = root.val;
maxDepth[0] = currDepth;
return;
}
}
findDepth(root.left, maxDepth, sumOfDeepestLeaves, currDepth+1);
findDepth(root.right, maxDepth, sumOfDeepestLeaves, currDepth+1);
return;
}
}
answer six:
[Java] Short & Concise
class Solution {
static int max = -1;
static int sum = 0;
public static void func(TreeNode root, int level){
if(root == null) return;
if(level > max){
max = level;
sum = root.val;
} else if(max == level) sum += root.val;
func(root.left, level + 1);
func(root.right, level + 1);
}
public int deepestLeavesSum(TreeNode root) {
sum = 0;
max = 0;
func(root, 0);
return sum;
}
}