Beispiel #1
0
        def helper(p: TreeNode):
            nonlocal pre
            if not p:
                return p
            helper(p.right)
            helper(p.left)
            p.left, p.right = None, pre
            pre = p

        helper(root)


# TESTS
for tree, expected in [
    ("#", "#"),
    ("0,#,#", "0,#,#"),
    ("1,2,#,#,#", "1,#,2,#,#"),
    ("1,#,2,#,#", "1,#,2,#,#"),
    ("1,2,#,#,3,#,#", "1,#,2,#,3,#,#"),
    ("1,2,3,#,#,#,#", "1,#,2,#,3,#,#"),
    ("1,#,2,#,3,#,#", "1,#,2,#,3,#,#"),
    ("1,2,3,#,#,4,#,#,5,#,6,#,#", "1,#,2,#,3,#,4,#,5,#,6,#,#"),
]:
    sol = Solution()
    root = TreeNode.deserialize(tree)
    sol.flattenV2(root)
    actual = TreeNode.serialize(root)
    print("Flatten", tree, "->", actual)
    assert actual == expected
                return 0, None
            left_depth, left = deepest(root.left)
            right_depth, right = deepest(root.right)
            if left_depth == right_depth:
                return left_depth + 1, root
            elif left_depth > right_depth:
                return left_depth + 1, left
            else:
                return right_depth + 1, right

        return deepest(root)[1]


# TESTS
for tree, expected in [
    ("1,#,#", "1,#,#"),
    ("1,2,#,#,#", "2,#,#"),
    ("0,1,#,2,#,#,3,#,#", "2,#,#"),
    ("3,5,6,#,#,2,7,#,#,4,#,#,1,0,#,#,8,#,#", "2,7,#,#,4,#,#"),
    (
        "1,2,4,#,#,5,8,10,#,#,11,#,#,9,12,#,#,13,#,#,3,6,#,#,#",
        "5,8,10,#,#,11,#,#,9,12,#,#,13,#,#",
    ),
]:
    sol = Solution()
    actual = TreeNode.serialize(
        sol.lcaDeepestLeaves(TreeNode.deserialize(tree)))
    print("The lowest common ancestor of its deepest leaves in", tree, "->",
          actual)
    assert actual == expected
Beispiel #3
0
                rtail = node
            return head, rtail

        head, _ = helper(root)
        return head

    def increasingBST(self, root: TreeNode, nxt: TreeNode = None) -> TreeNode:
        if not root:
            return nxt
        head = self.increasingBST(root.left, root)
        root.left = None
        root.right = self.increasingBST(root.right, nxt)
        return head


# TESTS
for tree, expected in [
    ("1,#,#", "1,#,#"),
    ("1,#,2,#,#", "1,#,2,#,#"),
    ("2,1,#,#,#", "1,#,2,#,#"),
    ("5,1,#,#,7,#,#", "1,#,5,#,7,#,#"),
    ("3,2,1,#,#,#,4,#,#,", "1,#,2,#,3,#,4,#,#"),
    ("6,#,8,7,#,#,9,#,#", "6,#,7,#,8,#,9,#,#"),
    ("5,3,2,1,#,#,#,4,#,#,6,#,8,7,#,#,9,#,#", "1,#,2,#,3,#,4,#,5,#,6,#,7,#,8,#,9,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.increasingBSTV1(TreeNode.deserialize(tree)))
    print("Increasing BST of", tree, "->", actual)
    assert actual == expected
    assert expected == TreeNode.serialize(sol.increasingBST(TreeNode.deserialize(tree)))
Beispiel #4
0
class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return None
        if root.val == val:
            return root
        elif val < root.val:
            return self.searchBST(root.left, val)
        else:
            return self.searchBST(root.right, val)


# TESTS
tests = [
    ["#", 0, None],
    ["1,#,#", 1, 1],
    ["4,2,1,#,#,3,#,#,7,#,#", 2, 2],
    ["4,2,1,#,#,3,#,#,7,#,#", 1, 1],
    ["4,2,1,#,#,3,#,#,7,#,#", 7, 7],
    ["4,2,1,#,#,3,#,#,7,#,#", 5, None],
]
for t in tests:
    sol = Solution()
    actual = sol.searchBST(TreeNode.deserialize(t[0]), t[1])
    print("Search", t[1], "in", t[0], "->", TreeNode.serialize(actual))
    if t[2] is None:
        assert actual is None
    else:
        assert actual.val == t[2]
Beispiel #5
0

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return root
        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left, root.right = right, left
        return root


# TESTS
for tree, expected in [
    ["#", "#"],
    ["1", "1,#,#"],
    ["1,2,#,#,#", "1,#,2,#,#"],
    ["1,#,2,#,#", "1,2,#,#,#"],
    ["1,2,#,#,3,#,#", "1,3,#,#,2,#,#"],
    ["1,2,3,#,#,#,#", "1,#,2,#,3,#,#"],
    ["1,#,2,#,3,#,#", "1,2,3,#,#,#,#"],
    ["1,2,3,4,#,#,#,#,#", "1,#,2,#,3,#,4,#,#"],
    ["1,#,2,#,3,#,4,#,#", "1,2,3,4,#,#,#,#,#"],
    ["1,#,2,3,4,#,#,#,#", "1,2,#,3,#,4,#,#,#"],
    ["1,#,2,3,#,#,4,#,#", "1,2,4,#,#,3,#,#,#"],
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.invertTree(TreeNode.deserialize(tree)))
    print("Invert tree", tree, "->", actual)
    assert actual == expected
Beispiel #6
0
from local_packages.binary_tree import TreeNode


class Solution:
    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return TreeNode(val)
        if val < root.val:
            root.left = self.insertIntoBST(root.left, val)
        else:
            root.right = self.insertIntoBST(root.right, val)
        return root


# TESTS
tests = [
    ("#", 1, "1,#,#"),
    ("4,2,1,#,#,3,#,#,7,#,#", 5, "4,2,1,#,#,3,#,#,7,5,#,#,#"),
    (
        "40,20,10,#,#,30,#,#,60,50,#,#,70,#,#",
        25,
        "40,20,10,#,#,30,25,#,#,#,60,50,#,#,70,#,#",
    ),
]
for tree, val, expected in tests:
    sol = Solution()
    actual_tree = sol.insertIntoBST(TreeNode.deserialize(tree), val)
    actual = TreeNode.serialize(actual_tree)
    print("Insert", val, "into", tree, "->", actual)
    assert actual == expected
Beispiel #7
0
            root.left = self.deleteNode(root.left, key)
        elif key > root.val:
            root.right = self.deleteNode(root.right, key)
        else:  # found the key
            if root.left is None:
                return root.right
            if root.right is None:
                return root.left
            min_val = self.findMin(root.right)
            root.val = min_val
            root.right = self.deleteNode(root.right, min_val)
        return root


# TESTS
for tree, key, expected in [
    ["#", 1, "#"],
    ["1,#,#", 2, "1,#,#"],
    ["1,#,#", 1, "#"],
    ["1,#,2,#,#", 1, "2,#,#"],
    ["2,1,#,#,3,#,#", 2, "3,1,#,#,#"],
    ["2,1,#,#,3,#,#", 3, "2,1,#,#,#"],
    ["5,3,2,#,#,4,#,#,6,#,7,#,#", 3, "5,4,2,#,#,#,6,#,7,#,#"],
]:
    sol = Solution()
    actual = TreeNode.serialize(
        sol.deleteNode(TreeNode.deserialize(tree), key)
    )
    print("Delete", key, "from", tree, "->", actual)
    assert actual == expected
Beispiel #8
0
from local_packages.binary_tree import TreeNode


class Solution:
    def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
        if not root:
            return root
        if root.val < low:
            return self.trimBST(root.right, low, high)
        elif root.val > high:
            return self.trimBST(root.left, low, high)
        else:
            root.left = self.trimBST(root.left, low, root.val)
            root.right = self.trimBST(root.right, root.val, high)
            return root


# TESTS
for tree, low, high, expected in [
    ("1,0,#,#,2,#,#", 1, 2, "1,#,2,#,#"),
    ("3,0,#,2,1,#,#,#,4,#,#", 1, 3, "3,2,1,#,#,#,#"),
    ("1,#,#", 1, 2, "1,#,#"),
    ("1,#,2,#,#", 1, 3, "1,#,2,#,#"),
    ("1,#,2,#,#", 2, 4, "2,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.trimBST(TreeNode.deserialize(tree), low, high))
    print("Trim BST", tree, "->", actual)
    assert actual == expected

Beispiel #9
0
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
from typing import List, Optional
from functools import lru_cache
from local_packages.binary_tree import TreeNode


class Solution:
    def generateTrees(self, n: int) -> List[Optional[TreeNode]]:
        @lru_cache
        def trees(first: int, last: int) -> List[Optional[TreeNode]]:
            return [
                TreeNode(root, left, right)
                for root in range(first, last + 1)
                for left in trees(first, root - 1)
                for right in trees(root + 1, last)
            ] or [None]

        return trees(1, n)


# TESTS
for n in range(1, 5):
    sol = Solution()
    actual = sol.generateTrees(n)
    print("Unique BST of n =", n, "->", [TreeNode.serialize(t) for t in actual])
Beispiel #10
0
#         self.val = val
#         self.left = left
#         self.right = right
from typing import List
from local_packages.binary_tree import TreeNode


class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder:
            return None
        i = inorder.index(preorder[0])
        return TreeNode(
            val=preorder[0],
            left=self.buildTree(preorder[1 : i + 1], inorder[:i]),
            right=self.buildTree(preorder[i + 1 :], inorder[i + 1 :]),
        )


# TESTS
for preorder, inorder, expected in [
    ([1], [1], "1,#,#"),
    ([1, 2], [2, 1], "1,2,#,#,#"),
    ([1, 2], [1, 2], "1,#,2,#,#"),
    ([3, 9, 20, 15, 7], [9, 3, 15, 20, 7], "3,9,#,#,20,15,#,#,7,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.buildTree(preorder, inorder))
    print("Build Tree ->", actual)
    assert actual == expected
Beispiel #11
0
            return None
        if not head.next:
            return TreeNode(head.val)

        pslow, slow, fast = None, head, head
        while fast and fast.next:
            pslow, slow = slow, slow.next
            fast = fast.next.next
        pslow.next = None

        return TreeNode(
            slow.val,
            left=self.sortedListToBST(head),
            right=self.sortedListToBST(slow.next),
        )


# TESTS
for array, expected in [
    ([-10, -3, 0, 5, 9], "0,-3,-10,#,#,#,9,5,#,#,#"),
    ([], "#"),
    ([0], "0,#,#"),
    ([1, 3], "3,1,#,#,#"),
    ([1, 2, 3, 4], "3,2,1,#,#,#,4,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.sortedListToBST(
        ListNode.from_array(array)))
    print("Convert sorted list", array, "to BST ->", actual)
    assert actual == expected
Beispiel #12
0
#         self.right = right
from local_packages.binary_tree import TreeNode


class Solution:
    def convertBST(self, root: TreeNode) -> TreeNode:
        def fold(p: TreeNode, s: int) -> int:
            if not p:
                return s
            p.val += fold(p.right, s)
            return fold(p.left, p.val)

        fold(root, 0)
        return root


# TESTS
for tree, expected in [
    (
        "4,1,0,#,#,2,#,3,#,#,6,5,#,#,7,#,8,#,#",
        "30,36,36,#,#,35,#,33,#,#,21,26,#,#,15,#,8,#,#",
    ),
    ("0,#,1,#,#", "1,#,1,#,#"),
    ("1,0,#,#,2,#,#", "3,3,#,#,2,#,#"),
    ("3,2,1,#,#,#,4,#,#", "7,9,10,#,#,#,4,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.convertBST(TreeNode.deserialize(tree)))
    print("Convert BST", tree, "to greater tree ->", actual)
    assert actual == expected
            if not root:
                return 0, None
            left_depth, left = deepest(root.left)
            right_depth, right = deepest(root.right)
            if left_depth == right_depth:
                return left_depth + 1, root
            elif left_depth > right_depth:
                return left_depth + 1, left
            else:
                return right_depth + 1, right

        return deepest(root)[1]


# TESTS
for tree, expected in [
    ("1,#,#", "1,#,#"),
    ("1,2,#,#,#", "2,#,#"),
    ("0,1,#,2,#,#,3,#,#", "2,#,#"),
    ("3,5,6,#,#,2,7,#,#,4,#,#,1,0,#,#,8,#,#", "2,7,#,#,4,#,#"),
    (
        "1,2,4,#,#,5,8,10,#,#,11,#,#,9,12,#,#,13,#,#,3,6,#,#,#",
        "5,8,10,#,#,11,#,#,9,12,#,#,13,#,#",
    ),
]:
    sol = Solution()
    actual = TreeNode.serialize(
        sol.subtreeWithAllDeepest(TreeNode.deserialize(tree)))
    print("Smallest Subtree with all the Deepest Nodes in", tree, "->", actual)
    assert actual == expected
Beispiel #14
0
            if not root:
                return True
            if left_not_contain_1 := not_contain_1(root.left):
                root.left = None
            if right_not_contain_1 := not_contain_1(root.right):
                root.right = None
            return left_not_contain_1 and right_not_contain_1 and root.val == 0

        return None if not_contain_1(root) else root

    def pruneTreeV2(self, root: TreeNode) -> TreeNode:
        if not root:
            return None
        root.left = self.pruneTree(root.left)
        root.right = self.pruneTree(root.right)
        if not root.left and not root.right and not root.val:
            return None
        return root


# TESTS
for tree, expected in [
    ("1,#,0,0,#,#,1,#,#", "1,#,0,#,1,#,#"),
    ("1,0,0,#,#,0,#,#,1,0,#,#,1,#,#", "1,#,1,#,1,#,#"),
    ("1,1,1,0,#,#,#,1,#,#,0,0,#,#,1,#,#", "1,1,1,#,#,1,#,#,0,#,1,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.pruneTree(TreeNode.deserialize(tree)))
    print("Prune subtree non containing 1 from", tree, "->", actual)
    assert actual == expected
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
from local_packages.binary_tree import TreeNode
from typing import List


class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if not nums:
            return None
        mid = len(nums) // 2
        return TreeNode(
            nums[mid],
            self.sortedArrayToBST(nums[:mid]),
            self.sortedArrayToBST(nums[mid + 1:]),
        )


# TESTS
for nums, expected in [
    ([-10, -3, 0, 5, 9], "0,-3,-10,#,#,#,9,5,#,#,#"),
    ([1, 3], "3,1,#,#,#"),
    ([], "#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.sortedArrayToBST(nums))
    print("Convert", nums, "to BST ->", actual)
    assert actual == expected
Beispiel #16
0

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        assert len(inorder) == len(postorder)
        if len(inorder) == 0:
            return None
        root_index = inorder.index(postorder[-1])
        root = TreeNode(
            postorder[-1],
            self.buildTree(inorder[:root_index], postorder[:root_index]),
            self.buildTree(inorder[root_index + 1 :], postorder[root_index:-1]),
        )
        return root


# TESTS
tests = [
    ([], [], "#"),
    ([1], [1], "1,#,#"),
    ([2, 1], [2, 1], "1,2,#,#,#"),
    ([1, 2], [2, 1], "1,#,2,#,#"),
    ([2, 1, 3], [2, 3, 1], "1,2,#,#,3,#,#"),
    ([9, 3, 15, 20, 7], [9, 15, 7, 20, 3], "3,9,#,#,20,15,#,#,7,#,#"),
]
for t in tests:
    sol = Solution()
    actual = TreeNode.serialize(sol.buildTree(t[0], t[1]))
    print("Construct from", t[0], t[1], "->", actual)
    assert actual == t[2]
Beispiel #17
0

class Solution:
    def addOneRow(self,
                  root: TreeNode,
                  v: int,
                  d: int,
                  left: bool = True) -> TreeNode:
        if d == 1:
            nroot = TreeNode(v, root if left else None, None if left else root)
            return nroot
        if not root:
            return root
        root.left = self.addOneRow(root.left, v, d - 1, True)
        root.right = self.addOneRow(root.right, v, d - 1, False)
        return root


# TESTS
for tree, v, d, expected in [
    ("4,#,#", 1, 1, "1,4,#,#,#"),
    ("4,2,3,#,#,1,#,#,6,5,#,#,#", 1, 2, "4,1,2,3,#,#,1,#,#,#,1,#,6,5,#,#,#"),
    ("4,2,3,#,#,1,#,#,#", 1, 3, "4,2,1,3,#,#,#,1,#,1,#,#,#"),
    ("1,2,4,#,#,#,3,#,#", 5, 4, "1,2,4,5,#,#,5,#,#,#,3,#,#"),
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.addOneRow(TreeNode.deserialize(tree), v,
                                              d))
    print("Add a row", v, "to depth", d, "to tree", tree, "->", actual)
    assert actual == expected
Beispiel #18
0
#         self.right = None
from typing import List, Optional
from local_packages.binary_tree import TreeNode


class Solution:
    def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]:
        def build(xs: List[int], ubound: int) -> Optional[TreeNode]:
            if not xs or xs[-1] > ubound:
                return None
            root = TreeNode(xs.pop())
            root.left = build(xs, root.val)
            root.right = build(xs, ubound)
            return root

        return build(preorder[::-1], float("Inf"))


for preorder, expected in [
    [[], "#"],
    [[1], "1,#,#"],
    [[2, 1], "2,1,#,#,#"],
    [[2, 3], "2,#,3,#,#"],
    [[2, 1, 3], "2,1,#,#,3,#,#"],
    [[8, 5, 1, 7, 10, 12], "8,5,1,#,#,7,#,#,10,#,12,#,#"],
]:
    sol = Solution()
    actual = TreeNode.serialize(sol.bstFromPreorder(preorder))
    print("BST from preorder traversal", preorder, "->", actual)
    assert actual == expected