Esempio n. 1
0
 def helper(in_left=0, in_right=len(inorder)):
     nonlocal pre_idx
     if in_left == in_right:
         return None
     root_val = preorder[pre_idx]
     root = Tree(root_val)
     index = idx_map[root_val]
     pre_idx += 1
     root.left = helper(in_left, index)
     root.right = helper(index + 1, in_right)
     return root
Esempio n. 2
0
def make_tree(happy_tree) -> Tree:
    if isinstance(happy_tree[0], int): return Tree(happy_tree[0])
    branches = happy_tree[0][1]
    root = Tree(happy_tree[0][0])
    prev = root
    for ix, branch in enumerate(happy_tree):
        lefts = branch[1]
        if lefts:
            prev.left = make_tree(lefts)
        if ix == 0: continue
        t = Tree(branch[0])
        prev.right = t
        prev = t
    return root
Esempio n. 3
0
    def traverse_find(
        self,
        root: Optional[Tree],
        target: int,
        *,
        depth: int = 0,
        parent: Tree,
    ) -> Tuple[int, Tree]:
        if root is None:
            return -1, Tree(-1)

        if root.v == target: return depth, parent

        depth_1, parent_1 = self.traverse_find(root.left,
                                               target,
                                               depth=depth + 1,
                                               parent=root)
        depth_2, parent_2 = self.traverse_find(root.right,
                                               target,
                                               depth=depth + 1,
                                               parent=root)

        if depth_1 > depth_2:
            return depth_1, parent_1
        else:
            return depth_2, parent_2
Esempio n. 4
0
 def insertIntoBST(self, root, val):
     if root == None:
         return Tree(val)
     if val < root.val:
         root.left = self.insertIntoBST(root.left, val)
     else:
         root.right = self.insertIntoBST(root.right, val)
     return root
Esempio n. 5
0
 def isCousins(self, root: Tree, x: int, y: int) -> bool:
     depth_x, parent_x = self.traverse_find(
         root, x, parent=Tree(-1))  # sentinel parent
     depth_y, parent_y = self.traverse_find(
         root, y, parent=Tree(-1))  # sentinel parent
     return parent_x != parent_y and depth_x == depth_y
Esempio n. 6
0
        if root.v == target: return depth, parent

        depth_1, parent_1 = self.traverse_find(root.left,
                                               target,
                                               depth=depth + 1,
                                               parent=root)
        depth_2, parent_2 = self.traverse_find(root.right,
                                               target,
                                               depth=depth + 1,
                                               parent=root)

        if depth_1 > depth_2:
            return depth_1, parent_1
        else:
            return depth_2, parent_2

    # get the depth of x, get the depth of y
    # if both are on the same depth AND parents different = cousins
    def isCousins(self, root: Tree, x: int, y: int) -> bool:
        depth_x, parent_x = self.traverse_find(
            root, x, parent=Tree(-1))  # sentinel parent
        depth_y, parent_y = self.traverse_find(
            root, y, parent=Tree(-1))  # sentinel parent
        return parent_x != parent_y and depth_x == depth_y


if __name__ == "__main__":
    t = Tree(1, Tree(2, None, Tree(4)), Tree(3))
    s = Solution()
    s.isCousins(t, 2, 3)
    ...
Esempio n. 7
0
#!/usr/bin/env python
from solutions.minions import Tree
from typing import List

# Breadth First Search
# You move each level at a time
# all the children of the current level nodes are printed left to right

# --------------------- BREADTH FIRST SEARCHES ------------------------
bfs_tree = Tree(1, Tree(2, Tree(4), Tree(5)), Tree(3))


def breadth_first_search(tree: Tree, prev_children: List[Tree] = None) -> None:
    if prev_children is None: print(tree.v)
    immediate_children = []
    if prev_children:
        for child in prev_children:
            if child is not None:
                print(child.v)
                immediate_children.append(child.left)
                immediate_children.append(child.right)
    else:
        immediate_children = [tree.left, tree.right]
    # ! this check is very inefficient
    if all(x is None for x in immediate_children): return
    return breadth_first_search(tree, immediate_children)


# ----------------------- DEPTH FIRST SEARCHES --------------------------
# you traverse down as far as possible. However, the order in which you print
# varies between the below three
Esempio n. 8
0
#!/usr/bin/env python
from typing import Optional
from solutions.minions import Tree


# ! S=O(N) number of nodes are stored in the recursion stack frames. average case though is O(H) height of the tree
# T = O(N)
def tree_diamter(t: Tree) -> int:
    ans = 0

    def depth(t: Optional[Tree]) -> int:
        nonlocal ans

        if t is None: return 0

        L = depth(t.left)
        R = depth(t.right)

        ans = max(ans, L + R)

        return max(L, R) + 1

    return depth(t)


if __name__ == '__main__':
    print(tree_diamter(Tree(1, Tree(2), Tree(3))))