Skip to content

Binary Tree BFS

Table of Contents

102. Binary Tree Level Order Traversal

from collections import deque
from typing import List, Optional

from binarytree import Node as TreeNode
from binarytree import build


def levelOrder(root: Optional[TreeNode]) -> List[List[int]]:
    if not root:
        return []

    q = deque([root])
    res = []

    while q:
        level = []
        size = len(q)

        for _ in range(size):
            cur = q.popleft()
            level.append(cur.val)

            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)

        res.append(level)

    return res


tree = build([3, 9, 20, None, None, 15, 7])
print(tree)
#   3___
#  /    \
# 9     _20
#      /   \
#     15    7
print(levelOrder(tree))  # [[3], [9, 20], [15, 7]]

103. Binary Tree Zigzag Level Order Traversal

from collections import deque
from typing import List, Optional

from binarytree import Node as TreeNode
from binarytree import build


def zigzagLevelOrder(root: Optional[TreeNode]) -> List[List[int]]:
    if not root:
        return []

    q = deque([root])
    res = []

    while q:
        level = []
        size = len(q)

        for _ in range(size):
            cur = q.popleft()
            level.append(cur.val)

            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)

        res.append(level if not len(res) % 2 else level[::-1])

    return res


if __name__ == "__main__":
    tree = build([3, 9, 20, None, None, 15, 7])
    print(tree)
    #   3___
    #  /    \
    # 9     _20
    #      /   \
    #     15    7
    assert zigzagLevelOrder(tree) == [[3], [20, 9], [15, 7]]

107. Binary Tree Level Order Traversal II

from collections import deque
from typing import List, Optional

from binarytree import Node as TreeNode
from binarytree import build


def levelOrderBottom(root: Optional[TreeNode]) -> List[List[int]]:
    if not root:
        return []

    res = []
    q = deque([root])

    while q:
        level = []
        n = len(q)

        for _ in range(n):
            cur = q.popleft()
            level.append(cur.val)

            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)

        res.append(level)

    return res[::-1]


tree = build([3, 9, 20, None, None, 15, 7])
print(tree)
#   3___
#  /    \
# 9     _20
#      /   \
#     15    7
print(levelOrderBottom(tree))  # [[15, 7], [9, 20], [3]]

199. Binary Tree Right Side View

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import List, Optional

from binarytree import Node as TreeNode
from binarytree import build


# Binary Tree BFS
def rightSideViewBFS(root: Optional[TreeNode]) -> List[int]:
    if not root:
        return []

    q = deque([root])
    res = []

    while q:
        n = len(q)
        for i in range(n):
            node = q.popleft()
            if i == n - 1:
                res.append(node.val)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

    return res


# Binary Tree DFS
def rightSideViewDFS(root: Optional[TreeNode]) -> List[int]:
    """后序遍历,先右后左,遇到的第一个节点就是该深度的最右侧节点"""
    ans = []

    def dfs(node, depth):
        if node is None:
            return
        if depth == len(ans):  # 这个深度首次遇到
            ans.append(node.val)

        dfs(node.right, depth + 1)
        dfs(node.left, depth + 1)

    dfs(root, 0)

    return ans


if __name__ == "__main__":
    root = [1, 2, 2, 3, 4, None, 3, None, None, 5]
    root = build(root)
    print(root)
    #     ____1
    #    /     \
    #   2__     2
    #  /   \     \
    # 3     4     3
    #      /
    #     5
    assert rightSideViewBFS(root) == [1, 2, 3, 5]
    assert rightSideViewDFS(root) == [1, 2, 3, 5]

513. Find Bottom Left Tree Value

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import Optional

from binarytree import build


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def findBottomLeftValue(root: Optional[TreeNode]) -> int:
    if not root:
        return 0

    queue = deque([root])
    result = 0

    while queue:
        size = len(queue)

        for i in range(size):
            node = queue.popleft()
            if i == 0:
                result = node.val

            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

    return result


root = [1, 2, 2, 3, 4, None, None, None, None, 5]
root = build(root)
print(root)
#     ____1
#    /     \
#   2__     2
#  /   \
# 3     4
#      /
#     5

print(findBottomLeftValue(root))  # 5

515. Find Largest Value in Each Tree Row

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import List, Optional

from binarytree import build


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def largestValues(root: Optional[TreeNode]) -> List[int]:
    if not root:
        return []

    queue = deque([root])
    result = []

    while queue:
        levelMax = float("-inf")
        for _ in range(len(queue)):
            node = queue.popleft()

            levelMax = max(levelMax, node.val)

            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)

        result.append(levelMax)

    return result


root = [1, 2, 2, 3, 4, None, None, None, None, 5]
root = build(root)
print(root)
#     ____1
#    /     \
#   2__     2
#  /   \
# 3     4
#      /
#     5
print(largestValues(root))  # [1, 2, 4, 5]

637. Average of Levels in Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import List, Optional

from binarytree import Node as TreeNode
from binarytree import build


# Binary Tree BFS
def averageOfLevels(root: Optional[TreeNode]) -> List[float]:
    if not root:
        return []

    q = deque([root])
    res = []

    while q:
        n = len(q)
        level = 0
        for _ in range(n):
            cur = q.popleft()
            level += cur.val

            if cur.left:
                q.append(cur.left)
            if cur.right:
                q.append(cur.right)

        res.append(float(level / n))

    return res


if __name__ == "__main__":
    root = [3, 9, 20, None, None, 15, 7]
    root = build(root)
    print(root)
    #   3___
    #  /    \
    # 9     _20
    #      /   \
    #     15    7
    assert averageOfLevels(root) == [3.00000, 14.50000, 11.00000]

1161. Maximum Level Sum of a Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


# BFS
def maxLevelSum(root: Optional[TreeNode]) -> int:
    if not root:
        return 0

    q = deque([root])
    res = 0
    maxSum = float("-inf")
    level = 1

    while q:
        n = len(q)
        curSum = 0

        for _ in range(n):
            node = q.popleft()
            curSum += node.val
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

        if curSum > maxSum:
            maxSum = curSum
            res = level
        level += 1

    return res


root = [1, 7, 0, 7, -8, None, None]
root = build(root)
print(root)
#     ___1
#    /    \
#   7      0
#  / \
# 7   -8
print(maxLevelSum(root))  # 2

993. Cousins in Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from math import inf
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


def is_cousins_bfs(root: Optional[TreeNode], x: int, y: int) -> bool:
    if not root:
        return False

    q = deque([(root, inf)])

    while q:
        size = len(q)
        p1, p2 = None, None

        for _ in range(size):
            cur, par = q.popleft()
            val = cur.val
            if x == val:
                p1 = par
            if y == val:
                p2 = par

            if cur.left:
                q.append((cur.left, val))
            if cur.right:
                q.append((cur.right, val))

        # Check if both found at same level
        if p1 and p2:
            return p1 != p2  # Same level, different parents
        elif p1 or p2:
            return False  # Only one found at this level

    return False


if __name__ == "__main__":
    root = build([1, 2, 3, None, 4, None, 5])
    assert is_cousins_bfs(root, 5, 4)
    root = build([1, 2, 3, None, 4])
    assert not is_cousins_bfs(root, 2, 3)
    root = build([1, 2, 3, 4])
    assert not is_cousins_bfs(root, 4, 3)

2583. Kth Largest Sum in a Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Breadth First Search, Sorting, Binary Tree

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


# BFS
def kthLargestLevelSum(root: Optional[TreeNode], k: int) -> int:
    if not root:
        return 0
    sums = []
    q = deque([root])

    while q:
        size = len(q)
        level = 0
        for _ in range(size):
            node = q.popleft()
            level += node.val
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        sums.append(level)

    if len(sums) < k:
        return -1

    sums.sort()
    return sums[-k]


root = [5, 8, 9, 2, 1, 3, 7, 4, 6]
root = build(root)
k = 2
print(kthLargestLevelSum(root, k))  # 13

1302. Deepest Leaves Sum

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


# BFS
def deepestLeavesSum(root: Optional[TreeNode]) -> int:
    if not root:
        return 0

    q = deque([root])

    while q:
        n = len(q)
        res = 0
        for _ in range(n):
            node = q.popleft()
            res += node.val
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

    return res


root = [1, 2, 3, 4, 5, None, 6, 7, None, None, None, None, None, 8]
root = build(root)
print(root)
#       __1
#      /   \
#     2     3__
#    / \       \
#   4   5       6
#  /           /
# 7           8
print(deepestLeavesSum(root))  # 15

2415. Reverse Odd Levels of Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


def reverseOddLevels(root: Optional[TreeNode]) -> Optional[TreeNode]:
    if not root:
        return None

    q = deque([root])
    level = -1

    while q:
        size = len(q)
        nodes = []
        level += 1

        for _ in range(size):
            node = q.popleft()
            nodes.append(node)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

        if level % 2 == 1:
            i, j = 0, len(nodes) - 1
            while i < j:
                nodes[i].val, nodes[j].val = nodes[j].val, nodes[i].val
                i += 1
                j -= 1

    return root


if __name__ == "__main__":
    root = build([2, 3, 5, 8, 13, 21, 34])
    print(root)
    #     ___2___
    #    /       \
    #   3        _5
    #  / \      /  \
    # 8   13   21   34
    print(reverseOddLevels(root))
    #     ___2___
    #    /       \
    #   5        _3
    #  / \      /  \
    # 8   13   21   34

1609. Even Odd Tree

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


def isEvenOddTree(root: Optional[TreeNode]) -> bool:
    if not root:
        return True

    q = deque([root])
    level = 0

    while q:
        size = len(q)
        prev = None

        for _ in range(size):
            node = q.popleft()

            if level % 2 == 0:
                if node.val % 2 == 0:
                    return False
                if prev and node.val <= prev:
                    return False
            else:
                if node.val % 2 == 1:
                    return False
                if prev and node.val >= prev:
                    return False

            prev = node.val

            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

        level += 1

    return True


if __name__ == "__main__":
    root = build([5, 4, 2, 3, 3, 7])
    print(root)
    #     __5__
    #    /     \
    #   4       2
    #  / \     /
    # 3   3   7
    assert isEvenOddTree(root) is False

623. Add One Row to Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from copy import deepcopy
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


# BFS
def addOneRow_bfs(
    root: Optional[TreeNode], val: int, depth: int
) -> Optional[TreeNode]:
    if not root:
        return None

    if depth == 1:
        new = TreeNode(val)
        new.left = root
        return new

    q = deque([root])
    cur = 1

    while q:
        size = len(q)
        for _ in range(size):
            node = q.popleft()

            if cur == depth - 1:
                old_left, old_right = node.left, node.right
                node.left, node.right = TreeNode(val), TreeNode(val)
                node.left.left = old_left
                node.right.right = old_right
            else:
                if node.left:
                    q.append(node.left)
                if node.right:
                    q.append(node.right)
        cur += 1

    return root


# DFS
def addOneRow_dfs(
    root: Optional[TreeNode], val: int, depth: int
) -> Optional[TreeNode]:
    if depth == 1:
        new = TreeNode(val)
        new.left = root
        return new

    def dfs(node, cur):
        if not node:
            return
        if cur == depth - 1:
            old_left, old_right = node.left, node.right
            node.left = TreeNode(val, old_left, None)
            node.right = TreeNode(val, None, old_right)
        else:
            dfs(node.left, cur + 1)
            dfs(node.right, cur + 1)

    dfs(root, 1)

    return root


if __name__ == "__main__":
    root = build([4, 2, 6, 3, 1, 5])
    print(root)
    #     __4__
    #    /     \
    #   2       6
    #  / \     /
    # 3   1   5
    print(addOneRow_bfs(deepcopy(root), 1, 2))
    #         4
    #        / \
    #     __1   1__
    #    /         \
    #   2           6
    #  / \         /
    # 3   1       5
    print(addOneRow_dfs(deepcopy(root), 1, 2))
    #         4
    #        / \
    #     __1   1__
    #    /         \
    #   2           6
    #  / \         /
    # 3   1       5

2471. Minimum Number of Operations to Sort a Binary Tree by Level

from collections import deque
from typing import Optional

from binarytree import Node as TreeNode
from binarytree import build


def _min_swaps_to_sort(nums):
    """
    Calculate the minimum number of swaps to sort the array.
    Method: Permutation Cycle
    """
    n = len(nums)
    arr = [(num, i) for i, num in enumerate(nums)]
    arr.sort(key=lambda x: x[0])

    visited = [False] * n
    res = 0

    for i in range(n):
        if visited[i] or arr[i][1] == i:
            continue

        cycle_len = 0
        j = i
        while not visited[j]:
            visited[j] = True
            j = arr[j][1]
            cycle_len += 1

        if cycle_len > 1:
            res += cycle_len - 1

    return res


def minimumOperations_bfs(root: Optional[TreeNode]) -> int:
    if not root:
        return 0

    res = 0
    q = deque([root])

    while q:
        size = len(q)
        level = []
        for _ in range(size):
            node = q.popleft()
            level.append(node.val)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)

        res += _min_swaps_to_sort(level)

    return res


if __name__ == "__main__":
    root = build([1, 4, 3, 7, 6, 8, 5, None, None, None, None, 9, None, 10])
    print(root)
    #     __1____
    #    /       \
    #   4         3___
    #  / \       /    \
    # 7   6     8     _5
    #          /     /
    #         9     10
    assert minimumOperations_bfs(root) == 3

863. All Nodes Distance K in Binary Tree

  • LeetCode | 力扣

  • Tags: Hash Table, Tree, Depth First Search, Breadth First Search, Binary Tree

from collections import deque
from typing import List

from binarytree import Node as TreeNode
from binarytree import build


# BFS
def distanceK(root: TreeNode, target: TreeNode, k: int) -> List[int]:
    parent = dict()

    def dfs(node, par=None):
        if node:
            parent[node] = par
            dfs(node.left, node)
            dfs(node.right, node)

    dfs(root)

    q = deque([(target, 0)])
    seen = set([target])

    while q:
        node, dist = q.popleft()

        if dist == k:
            return [node.val] + [node.val for node, _ in q]

        for nei in (node.left, node.right, parent[node]):
            if nei and nei not in seen:
                seen.add(nei)
                q.append((nei, dist + 1))

    return []


root = build([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4])
print(root)
#     ______3__
#    /         \
#   5__         1
#  /   \       / \
# 6     2     0   8
#      / \
#     7   4
target = root.left
k = 2
print(distanceK(root, target, k))  # [7, 4, 1]

2641. Cousins in Binary Tree II

  • LeetCode | 力扣

  • Tags: Hash Table, Tree, Depth First Search, Breadth First Search, Binary Tree

919. Complete Binary Tree Inserter

  • LeetCode | 力扣

  • Tags: Tree, Breadth First Search, Design, Binary Tree

331. Verify Preorder Serialization of a Binary Tree

958. Check Completeness of a Binary Tree

662. Maximum Width of Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

3157. Find the Level of Tree with Minimum Sum

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

1602. Find Nearest Right Node in Binary Tree

742. Closest Leaf in a Binary Tree

  • LeetCode | 力扣

  • Tags: Tree, Depth First Search, Breadth First Search, Binary Tree

1660. Correct a Binary Tree

  • LeetCode | 力扣

  • Tags: Hash Table, Tree, Depth First Search, Breadth First Search, Binary Tree

Comments