↓Skip to main content
  1. LeetCode/

LeetCode 958: Check Completeness of a Binary Tree

·2 mins· ·
LeetCode Medium Tree Binary-Tree Bfs
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2025-07-16

  • Submissions: Wrong Answer → Accepted (next day)

Approach
#

A complete binary tree has every level full except possibly the last, and the last level’s nodes are as far left as possible.

From a BFS point of view: list the nodes in level order, including empty children. After the first gap, no real node may appear.

My First Attempt: recursively checking both subtrees
#

def isCompleteTree(self, root):
    if root.val == None:
        return True
    completed_left = False
    completed_right = False
    if root.left:
        completed_left = self.isCompleteTree(root.left)
    if root.right:
        completed_right = self.isCompleteTree(root.right)

    completed = True
    if root.left and root.right:
        if not completed_left or not completed_right:
            completed = False
    else:
        if not completed_left and completed_right:
            completed = False
    return completed

The mistake is treating a global property as a local one. Two complete subtrees do not make a complete tree. For example, with a left subtree of height 2 and a right subtree of height 3, both are complete, but the combined last level is not left-aligned.

A recursive solution would also need to return heights and whether each subtree is perfect, which gets complicated. BFS is more direct.

Also, root.val == None checks the node’s value, not the node itself, so the line does nothing.

Solution
#

from collections import deque

class Solution:
    def isCompleteTree(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return True

        q = deque([root])
        while q[0] is not None:          # walk until the first gap
            node = q.popleft()
            q.append(node.left)          # push None on purpose
            q.append(node.right)

        while q and q[0] is None:        # drop the consecutive gaps
            q.popleft()

        return not q                     # any node after a gap breaks completeness

This is one of the few BFS problems that pushes None into the queue on purpose.

Complexity
#

Time O(n), space O(n).

Mistakes to Avoid
#

  • Concluding the whole tree is complete because both subtrees are.
  • Writing root.val == None when you mean root is None.

Interview Explanation
#

In level order, a complete binary tree never has a node after its first gap. I run BFS and push empty children too, stopping at the first None. Then I drop the run of None values; if anything is left in the queue, a node follows a gap, so the tree is not complete. Time and space are O(n).

Related

LeetCode 1008: Construct Binary Search Tree from Preorder Traversal
·2 mins
LeetCode Medium Tree Bst Binary-Tree Recursion
LeetCode 1008 note: splitting the array is O(n^2); recursing with an upper bound is O(n)
LeetCode 113: Path Sum II
·2 mins
LeetCode Medium Backtracking Tree Depth-First-Search Binary-Tree
LeetCode 113 note: backtrack with the current path and store a copy at a leaf whose total matches; values can be negative, so no early pruning
LeetCode 129: Sum Root to Leaf Numbers
·1 min
LeetCode Medium Tree Depth-First-Search Binary-Tree
LeetCode 129 note: on the way down multiply the current number by 10 and add the node’s value, adding it to the total at a leaf
LeetCode 222: Count Complete Tree Nodes
·2 mins
LeetCode Medium Binary-Search Bit-Manipulation Tree Binary-Tree
LeetCode 222 note: in a complete tree, equal leftmost depths on both sides mean one side is perfect, counted as 2^h - 1, for O(log² n)
LeetCode 236: Lowest Common Ancestor of a Binary Tree
·2 mins
LeetCode Medium Tree Depth-First-Search Binary-Tree Binary-Lifting
LeetCode 236 note: recursion returns whichever of p or q a subtree contains; finding something on both sides means they split here, so this node is the LCA
LeetCode 337: House Robber III
·2 mins
LeetCode Medium Dynamic-Programming Tree Depth-First-Search Binary-Tree
LeetCode 337 note: tree DP where each node returns the best (rob it, skip it) pair; not robbing alternate levels