# 404. Sum of Left Leaves

LeetCode Problem Link (opens new window)

Given a binary tree, calculate the sum of all left leaves in the tree.

Example:

404. Sum of Left Leaves1

# Approach

Firstly, note that it refers to left leaves, not the left-hand side of the binary tree, so do not immediately think of level-order traversal.

Since the problem does not clearly define a left leaf, let me provide a clear definition: Node A's left child is not null, and the left child has no children (meaning it is a leaf node), then Node A's left child is a left leaf node.

Consider the binary tree in the diagram below. What is the sum of its left leaves?

404. Sum of Left Leaves It is actually 0 because this tree does not have any left leaves!

Now, what about the sum of left leaves in this tree?

Diagram 2

With these two illustrations, you should have a clear understanding of the definition of a left leaf.

The current node cannot determine if it is a left leaf; it has to be determined by the parent node.

If a node's left child is not null, and both of the left child's children are null, a left leaf has been found, processed by the following code:

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    // Logic for handling left leaf node
}
1
2
3

# Recursive Method

The recursive traversal order is post-order (left-right-root) because the sum of the values of left leaves is accumulated through the return value of the recursive function.

Recursive three-step process:

  1. Define the parameters and return value of the recursive function

To determine the sum of the left leaf nodes of a tree, the root of the tree must be provided, and the return value is the sum, so it is of type int.

Using the function provided in the problem is sufficient.

  1. Define the termination condition

If a null node is reached, the sum of left leaves is obviously 0

if (root == NULL) return 0;
1

Note that only when the current node is a parent can it be checked if its child is a left leaf. So if the current node traversed is a leaf node, then its left leaf must also be 0. Therefore, the termination condition is:

if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 0; // This line is optional: omitting it would not affect the result, but it would cause the recursion to go one layer deeper.
1
2
  1. Define the logic for a single level of recursion

When a left leaf is encountered, record its value, and then recursively calculate the sum of left leaves for the left and right subtrees, adding them to get the sum for the entire tree.

The code is as follows:

int leftValue = sumOfLeftLeaves(root->left);    // Left
if (root->left && !root->left->left && !root->left->right) {
    leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right);  // Right

int sum = leftValue + rightValue;               // Root
return sum;
1
2
3
4
5
6
7
8

The complete recursive code is as follows:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (root == NULL) return 0;
        if (root->left == NULL && root->right == NULL) return 0;

        int leftValue = sumOfLeftLeaves(root->left);    // Left
        if (root->left && !root->left->left && !root->left->right) { // Left subtree is a left leaf situation
            leftValue = root->left->val;
        }
        int rightValue = sumOfLeftLeaves(root->right);  // Right

        int sum = leftValue + rightValue;               // Root
        return sum;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

The refined code is as follows:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if (root == NULL) return 0;
        int leftValue = 0;
        if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
            leftValue = root->left->val;
        }
        return leftValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
    }
};
1
2
3
4
5
6
7
8
9
10
11

The refined code doesn't really reveal the traversal method used. For beginners, learn from the first version.

# Iterative Method

This problem can be solved using pre-order, in-order, or post-order traversal as long as the left leaf nodes are identified. Referencing the article Binary Tree Iterative traversal (opens new window) and Unified Iterative Traversal of Binary Tree (opens new window), we can write an iterative pre-order traversal.

The judgment conditions are the same, and the code is as follows:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        stack<TreeNode*> st;
        if (root == NULL) return 0;
        st.push(root);
        int result = 0;
        while (!st.empty()) {
            TreeNode* node = st.top();
            st.pop();
            if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
                result += node->left->val;
            }
            if (node->right) st.push(node->right);
            if (node->left) st.push(node->left);
        }
        return result;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Summary

This problem requires the sum of left leaves, which can be a bit tricky because it's not possible to determine whether the current node is a left leaf.

In this case, the identification of the left leaf must be determined by the parent node.

In our usual binary tree problem-solving, we are accustomed to determining a node's properties by its children. In this problem, we determine a node's property by its parent.

I hope this problem expands your binary tree problem-solving approach.

# Other Language Versions

# Java:

Recursive

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) return 0;
        int leftValue = sumOfLeftLeaves(root.left);    // Left
        int rightValue = sumOfLeftLeaves(root.right);  // Right
                                                       
        int midValue = 0;
        if (root.left != null && root.left.left == null && root.left.right == null) { 
            midValue = root.left.val;
        }
        int sum = midValue + leftValue + rightValue;  // Root
        return sum;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Iterative

class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) return 0;
        Stack<TreeNode> stack = new Stack<> ();
        stack.add(root);
        int result = 0;
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            if (node.left != null && node.left.left == null && node.left.right == null) {
                result += node.left.val;
            }
            if (node.right != null) stack.add(node.right);
            if (node.left != null) stack.add(node.left);
        }
        return result;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Level-order Traversal Iterative Method
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        int sum = 0;
        if (root == null) return 0;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size -- > 0) {
                TreeNode node = queue.poll();
                if (node.left != null) { // Left node is not null
                    queue.offer(node.left);
                    if (node.left.left == null && node.left.right == null){ // Left leaf node
                        sum += node.left.val;
                    }
                }
                if (node.right != null) queue.offer(node.right);
            }
        }
        return sum;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# Python:

Recursive

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        if root.left is None and root.right is None:
            return 0
        
        leftValue = self.sumOfLeftLeaves(root.left)  # Left
        if root.left and not root.left.left and not root.left.right:  # Left subtree is a left leaf
            leftValue = root.left.val
            
        rightValue = self.sumOfLeftLeaves(root.right)  # Right

        sum_val = leftValue + rightValue  # Root
        return sum_val
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Refined recursive version

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        leftValue = 0
        if root.left is not None and root.left.left is None and root.left.right is None:
            leftValue = root.left.val
        return leftValue + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Iterative

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root):
        if root is None:
            return 0
        st = [root]
        result = 0
        while st:
            node = st.pop()
            if node.left and node.left.left is None and node.left.right is None:
                result += node.left.val
            if node.right:
                st.append(node.right)
            if node.left:
                st.append(node.left)
        return result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Go:

Recursive Method

func sumOfLeftLeaves(root *TreeNode) int {
    if root == nil {
        return 0
    }
    leftValue := sumOfLeftLeaves(root.Left)   // Left

    if root.Left != nil && root.Left.Left == nil && root.Left.Right == nil {
        leftValue = root.Left.Val             // Root
    }

    rightValue := sumOfLeftLeaves(root.Right) // Right

    return leftValue + rightValue
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Refined Recursive Version

func sumOfLeftLeaves(root *TreeNode) int {
    if root == nil {
        return 0
    }
    leftValue := 0
    if root.Left != nil && root.Left.Left == nil && root.Left.Right == nil {
        leftValue = root.Left.Val
    }
    return leftValue + sumOfLeftLeaves(root.Left) + sumOfLeftLeaves(root.Right)
}
1
2
3
4
5
6
7
8
9
10

Iterative Method (Pre-order Traversal)

func sumOfLeftLeaves(root *TreeNode) int {
        st := make([]*TreeNode, 0)
        if root == nil {
            return 0
        }
        st = append(st, root)
        result := 0

        for len(st) != 0 {
            node := st[len(st)-1]
            st = st[:len(st)-1]
            if node.Left != nil && node.Left.Left == nil && node.Left.Right == nil {
                result += node.Left.Val
            }
            if node.Right != nil {
                st = append(st, node.Right)
            }
            if node.Left != nil {
                st = append(st, node.Left)
            } 
        }

        return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# JavaScript:

Recursive Method

var sumOfLeftLeaves = function(root) {
    // Use post-order traversal recursively
    // 1. Define recursion function parameters
    const nodesSum = function(node) {
        // 2. Define termination condition
        if(node === null) {
            return 0;
        }
        let leftValue = nodesSum(node.left);
        let rightValue = nodesSum(node.right);
        // 3. Single layer recursion logic
        let midValue = 0;
        if(node.left && node.left.left === null && node.left.right === null) {
            midValue = node.left.val;
        }
        let sum = midValue + leftValue + rightValue;
        return sum;
    }
    return nodesSum(root);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Iterative Method

var sumOfLeftLeaves = function(root) {
   // Use level-order traversal
   if(root === null) {
       return null;
   }
   let queue = [];
   let sum = 0;
   queue.push(root);
   while(queue.length) {
     let node = queue.shift();
     if(node.left !== null && node.left.left === null && node.left.right === null) {
         sum+=node.left.val;
     }
     node.left && queue.push(node.left);
     node.right && queue.push(node.right);
   }
   return sum;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# TypeScript:

Recursive Method

function sumOfLeftLeaves(root: TreeNode | null): number {
    if (root === null) return 0;
    let midVal: number = 0;
    if (
        root.left !== null &&
        root.left.left === null &&
        root.left.right === null
    ) {
        midVal = root.left.val;
    }
    let leftVal: number = sumOfLeftLeaves(root.left);
    let rightVal: number = sumOfLeftLeaves(root.right);
    return midVal + leftVal + rightVal;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Iterative Method

function sumOfLeftLeaves(root: TreeNode | null): number {
    let helperStack: TreeNode[] = [];
    let tempNode: TreeNode;
    let sum: number = 0;
    if (root !== null) helperStack.push(root);
    while (helperStack.length > 0) {
        tempNode = helperStack.pop()!;
        if (
            tempNode.left !== null &&
            tempNode.left.left === null &&
            tempNode.left.right === null
        ) {
            sum += tempNode.left.val;
        }
        if (tempNode.right !== null) helperStack.push(tempNode.right);
        if (tempNode.left !== null) helperStack.push(tempNode.left);
    }
    return sum;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Swift:

Recursive Method

func sumOfLeftLeaves(_ root: TreeNode?) -> Int {
    guard let root = root else {
        return 0
    }

    let leftValue = sumOfLeftLeaves(root.left)
    let rightValue = sumOfLeftLeaves(root.right)

    var midValue: Int = 0
    if root.left != nil && root.left?.left == nil && root.left?.right == nil {
        midValue = root.left!.val
    }

    let sum = midValue + leftValue + rightValue
    return sum
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Iterative Method

func sumOfLeftLeaves(_ root: TreeNode?) -> Int {
    guard let root = root else {
        return 0
    }

    var stack = Array<TreeNode>()
    stack.append(root)
    var sum = 0

    while !stack.isEmpty {
        let lastNode = stack.removeLast()

        if lastNode.left != nil && lastNode.left?.left == nil && lastNode.left?.right == nil {
            sum += lastNode.left!.val
        }
        if let right = lastNode.right {
            stack.append(right)
        }
        if let left = lastNode.left {
            stack.append(left)
        }
    }
    return sum
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# C:

Recursive method:

int sumOfLeftLeaves(struct TreeNode* root){
    // Ending condition of recursion: if the current node is NULL, return 0
    if(!root)
        return 0;
    
    // Recursively calculate the sum of the left node for the left and right subtrees
    int leftValue = sumOfLeftLeaves(root->left);
    int rightValue = sumOfLeftLeaves(root->right);

    // If the left child of the current node exists and it is a leaf node, take its value
    int midValue = 0;
    if(root->left && (!root->left->left && !root->left->right))
        midValue = root->left->val;
    
    return leftValue + rightValue + midValue;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Iterative method:

int sumOfLeftLeaves(struct TreeNode* root){
    struct TreeNode* stack[1000];
    int stackTop = 0;

    // If the root node passed in is not NULL, push it onto the stack
    if(root)
        stack[stackTop++] = root;
    
    int sum = 0;
    // Perform loop as long as stack is not empty
    while(stackTop) {
        // Pop the top element of the stack
        struct TreeNode *topNode = stack[--stackTop];
        // If the left child of the top element is a left leaf node, add its value to sum
        if(topNode->left && (!topNode->left->left && !topNode->left->right))
            sum += topNode->left->val;
        
        // If the current top node has left and right children, push them onto the stack
        if(topNode->right)
            stack[stackTop++] = topNode->right;
        if(topNode->left)
            stack[stackTop++] = topNode->left;
    }
    return sum;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# Scala:

Recursive:

object Solution {
  def sumOfLeftLeaves(root: TreeNode): Int = {
    if(root == null) return 0
    var midValue = 0
    if(root.left != null && root.left.left == null && root.left.right == null){
      midValue = root.left.value
    }
    // return keyword can be omitted
    midValue + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right)
  }
}
1
2
3
4
5
6
7
8
9
10
11

Iterative:

object Solution {
  import scala.collection.mutable
  def sumOfLeftLeaves(root: TreeNode): Int = {
    val stack = mutable.Stack[TreeNode]()
    if (root == null) return 0
    stack.push(root)
    var sum = 0
    while (!stack.isEmpty) {
      val curNode = stack.pop()
      if (curNode.left != null && curNode.left.left == null && curNode.left.right == null) {
        sum += curNode.left.value // Add if condition is satisfied
      }
      if (curNode.right != null) stack.push(curNode.right)
      if (curNode.left != null) stack.push(curNode.left)
    }
    sum
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Rust:

Recursive

use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
    pub fn sum_of_left_leaves(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
        let mut res = 0;
        if let Some(node) = root {
            if let Some(left) = &node.borrow().left {
                if left.borrow().right.is_none() && left.borrow().right.is_none() {
                    res += left.borrow().val;
                }
            }
            res + Self::sum_of_left_leaves(node.borrow().left.clone())
                + Self::sum_of_left_leaves(node.borrow().right.clone())
        } else {
            0
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Iterative:

use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
    pub fn sum_of_left_leaves(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
        let mut res = 0;
        let mut stack = vec![root];
        while !stack.is_empty() {
            if let Some(node) = stack.pop().unwrap() {
                if let Some(left) = &node.borrow().left {
                    if left.borrow().left.is_none() && left.borrow().right.is_none() {
                        res += left.borrow().val;
                    }
                    stack.push(Some(left.to_owned()));
                }
                if let Some(right) = &node.borrow().right {
                    stack.push(Some(right.to_owned()));
                }
            }
        }
        res
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# C#

// Recursive
public int SumOfLeftLeaves(TreeNode root)
{
    if (root == null) return 0;

    int leftValue = SumOfLeftLeaves(root.left);
    if (root.left != null && root.left.left == null && root.left.right == null)
    {
        leftValue += root.left.val;
    }
    int rightValue = SumOfLeftLeaves(root.right);
    return leftValue + rightValue;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
Last updated:: 9/4/2025, 3:19:38 PM
Copyright © 2025 keetcoder