def build(stop=None):
     if inorder and inorder[-1] != stop:
         root = TreeNode(preorder.pop())
         root.left = build(root.val)
         inorder.pop()
         root.right = build(stop)
         return root
Example #2
0
 def make_binary_tree():
     root = TreeNode(5)
     l1_1, l1_2 = TreeNode(1), TreeNode(5)
     l2_1, l2_2, l2_3 = TreeNode(5), TreeNode(5), TreeNode(5)
     root.left, root.right = l1_1, l1_2
     l1_1.left, l1_1.right, l1_2.right = l2_1, l2_2, l2_3
     return root
 def build(bound=None):
     if not inorder or inorder[-1] == bound:
         return None
     root = TreeNode(postorder.pop())
     root.right = build(root.val)
     inorder.pop()
     root.left = build(bound)
     return root
Example #4
0
 def make_asymmetric_tree():
     root = TreeNode(1)
     l2_l, l2_r = TreeNode(2), TreeNode(2)
     l2_l_l3_l, l2_l_l3_r, l2_r_l3_l, l2_r_l3_r = None, TreeNode(
         3), None, TreeNode(3)
     root.left, root.right = l2_l, l2_r
     l2_l.left, l2_l.right, l2_r.left, l2_r.right = l2_l_l3_l, l2_l_l3_r, l2_r_l3_l, l2_r_l3_r
     return root
    def helper(self, left, right):
        if left > right:
            return None

        # always choose left middle node as a root
        p = (left + right) // 2

        # preorder traversal: node -> left -> right
        root = TreeNode(self.nums[p])
        root.left = self.helper(left, p - 1)
        root.right = self.helper(p + 1, right)
        return root
    def helper(self, left, right):
        if left > right:
            return None

        # always choose right middle node as a root
        p = (left + right) // 2
        # if left + right is odd, add 1 to p-index.
        if (left + right) % 2:
            p += 1

        # preorder traversal: node -> left -> right
        root = TreeNode(self.nums[p])
        root.left = self.helper(left, p - 1)
        root.right = self.helper(p + 1, right)
        return root
 def make_binary_tree():
     tn_left = TreeNode(9)
     tn_right = TreeNode(20)
     tn_root = TreeNode(3)
     tn_root.left = tn_left
     tn_root.right = tn_right
     tn_root.right.left = TreeNode(15)
     tn_root.right.right = TreeNode(7)
     return tn_root
Example #8
0
    def str2tree(self, s: str) -> TreeNode:
        num, stack = "", []

        for ch in s:
            if ch.isdigit() or ch == "-":
                num += ch
            elif ch == "(":  # start seq
                if num:  # prev seq has not been closed, remember in stack
                    stack.append(TreeNode(num))
                    num = ""
            else:  # close seq
                node = TreeNode(num) if num else stack.pop()  # use curr num seq, if present, or prev (unclosed)
                if not stack[-1].left:  # always start from left child
                    stack[-1].left = node
                else:
                    stack[-1].right = node
                num = ""

        return stack[-1] if stack else TreeNode(num) if s else None
Example #9
0
    def deserialize(self, data: str) -> Optional[TreeNode]:
        """ Decodes your encoded data to binary tree. """
        if data[0] == "#":
            return None

        vals = iter(
            data.split())  # make list iterator to request one item at a time
        root = TreeNode(int(next(vals)))
        q = collections.deque([root])

        while q:
            node = q.popleft()
            left, right = next(vals), next(vals)
            node.left = TreeNode(int(left)) if left != "#" else None
            node.right = TreeNode(int(right)) if right != "#" else None
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        return root
        def helper(in_left=0, in_right=len(inorder)):
            # The nonlocal statement causes the listed identifiers to refer to
            # previously bound variables in the nearest enclosing scope excluding globals.
            nonlocal pre_idx
            # if there is no elements to construct subtrees
            if in_left == in_right:
                return None

            # pick up pre_idx element as a root
            root_val = preorder[pre_idx]
            root = TreeNode(root_val)

            # root splits inorder list
            # into left and right subtrees
            index = idx_map[root_val]

            # recursion
            pre_idx += 1
            # build left subtree
            root.left = helper(in_left, index)
            # build right subtree
            root.right = helper(index + 1, in_right)
            return root
Example #11
0
 def make_binary_tree():
     root = TreeNode(5)
     l1_1, l1_2 = TreeNode(4), TreeNode(8)
     l2_1, l2_2, l2_3 = TreeNode(11), TreeNode(13), TreeNode(4)
     l3_1, l3_2, l3_3 = TreeNode(7), TreeNode(2), TreeNode(1)
     root.left, root.right = l1_1, l1_2
     l1_1.left, l1_2.left, l1_2.right = l2_1, l2_2, l2_3
     l2_1.left, l2_1.right, l2_3.right = l3_1, l3_2, l3_3
     return root
Example #12
0
                dfs(node.left)
                dfs(node.right)

                if node != root:
                    string_builder.append(")")

        string_builder = []
        dfs(root)
        return "".join(string_builder)


if __name__ == '__main__':
    solutions = [Solution(), Solution2()]

    bt1 = TreeNode(1)
    bt1.left, bt1.right = TreeNode(2), TreeNode(3)
    bt1.left.left = TreeNode(4)

    bt2 = TreeNode(1)
    bt2.left, bt2.right = TreeNode(2), TreeNode(3)
    bt2.left.right = TreeNode(4)

    tc = (
        (bt1, "1(2(4))(3)"),  # root = [1,2,3,4]
        (bt2, "1(2()(4))(3)"),  # root = [1,2,3,null,4]
    )
    for sol in solutions:
        for bt_root, expected_output in tc:
            actual_result = sol.tree2str(bt_root)
            assert actual_result == expected_output, f"{sol.__class__.__name__}: {actual_result} != {expected_output}"
    def averageOfLevels(self, root: TreeNode) -> List[float]:
        if not root:
            return []
        level_nums = collections.defaultdict(list)
        level = 0
        queue = [(root, level)]

        while queue:
            node, level = queue.pop(0)  # pop leftmost (tree node) first
            level_nums[level].append(node.val)
            if node.left:
                queue.append((node.left, level + 1))
            if node.right:
                queue.append((node.right, level + 1))
        return [
            sum(level_nums[i]) / len(level_nums[i]) for i in range(level + 1)
        ]


if __name__ == '__main__':
    solutions = [Solution, Solution2]
    root = TreeNode(3)
    root.left = TreeNode(9)
    root.right = TreeNode(20)
    root.right.left = TreeNode(15)
    root.right.right = TreeNode(7)
    expected = [3, 14.5, 11]
    for sol in solutions:
        res = sol().averageOfLevels(root)
        assert res == expected, f"{sol.__class__.__name__}: expected {expected}, got {res}"
Example #14
0
 def make_invalid_bst():
     n1 = TreeNode(1)
     n0 = TreeNode(2)
     n2 = TreeNode(3)
     n1.left, n1.right = n0, n2
     return n1