Skip to main content

Command Palette

Search for a command to run...

Leetcode 150

Tree

Updated
3 min read

Same Tree

Brute

def preorder(self, node, result):
        if not node:
            result.append(None)
            return
        result.append(node.val)
        self.preorder(node.left, result)
        self.preorder(node.right, result)


def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
    p_res = []
    q_res = []

    self.preorder(p, p_res)
    self.preorder(q, q_res)

    return True if p_res == q_res else False

Optimized

def isSameTree(p, q):
    if not p and not q:                # Base case 1
        return True
    if not p or not q:                 # Base case 2
        return False
    if p.val != q.val:                 # Base case 3
        return False
    return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)

Invert Binary Tree

Brute

def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return None
        stack = [root]
        while stack:
            node = stack.pop()
            node.left, node.right = node.right, node.left
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        return root

Optimized

def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return None
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

Symmetric Tree

Brute

def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        stack = [(root.left, root.right)]

        while stack:
            left, right = stack.pop(0)

            if not left and not right:
                continue
            if not left or not right:
                return False
            if left.val != right.val:
                return False
            stack.append((left.left, right.right))
            stack.append((left.right, right.left)) 
        return True

Optimized

def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def isMirror(self, node1, node2):
            if not node1 and not node2:
                return True
            if not node1 or not node2:
                return False
            return (t1.val == t2.val) and isMirror(t1.left, t2.right) and isMirror(t1.right, t2.left)
        return isMirror(root.left, root.right) if root else True

Construct Binary Tree from Preorder and Inorder Traversal

Brute

def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
        #get root from preorder
        #get left and right subtree from inorder
        if not preorder or not inorder:
            return None
        root = preorder[0] 
        root_node = TreeNode(root)
        index = inorder.index(root)
        root_node.left = self.buildTree(preorder[1:index+1], inorder[:index])
        root_node.right = self.buildTree(preorder[index+1:],inorder[index+1:])
        return root_node

Optimized

106. Construct Binary Tree from Inorder and Postorder Traversal

def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
        # Post L R Ro
        # Pre  L Ro R
        if not postorder or not inorder:
            return None

        root = postorder[-1] 
        root_node = TreeNode(root)
        index = inorder.index(root)
        left_inorder = inorder[:index]
        root_node.left = self.buildTree(left_inorder, postorder[:len(left_inorder)])
        root_node.right = self.buildTree(inorder[index+1:], postorder[len(left_inorder):-1])
        return root_node

Populating Next Right Pointers in Each Node II

from collections import deque
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return None

        queue = deque([root])

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

            for i in range(size):
                node = queue.popleft() 

                if prev:
                    prev.next = node
                prev = node

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

                if node.right:
                    queue.append(node.right)
            prev.next = None
        return root

Flatten Binary Tree to Linked List

def flatten(self, root: Optional[TreeNode]) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if not root:
            return

        queue = [root]
        prev = None

        while queue:
            node = queue.pop()

            if prev:
                prev.right = node
            prev = node

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

            if node.left:
                queue.append(node.left)
                node.left = None
        return root

Average of Levels in Binary Tree

def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        if not root:
            return []

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

        while queue:
            level_size = len(queue)
            level_sum = 0

            for i in range(level_size):
                node = queue.popleft()
                level_sum += node.val

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

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

            result.append(level_sum/level_size)
        return result