Ejemplo n.º 1
0
 def copy(self, source: TreeNode) -> TreeNode:
     if not source:
         return source
     res = TreeNode(source.val)
     res.left = self.copy(source.left)
     res.right = self.copy(source.right)
     return res
Ejemplo n.º 2
0
 def build(self, values, index, n):
     if index <= n and index in values:
         node = TreeNode(values[index])
         node.left = self.build(values, 2 * index + 1, n)
         node.right = self.build(values, 2 * index + 2, n)
         return node
     else:
         return None
Ejemplo n.º 3
0
 def insert(self, root: TreeNode, num: int) -> TreeNode:
     if not root:
         return TreeNode(num)
     if num < root.val:
         root.left = self.insert(root.left, num)
     else:
         root.right = self.insert(root.right, num)
     return root
 def __buildTree(self, inorder, postorder, idx_itr):
     if not inorder:
         return None
     pidx = next(idx_itr)
     root = TreeNode(postorder[pidx])
     idx = inorder.index(postorder[pidx])
     root.right = self.__buildTree(inorder[idx + 1:], postorder, idx_itr)
     root.left = self.__buildTree(inorder[:idx], postorder, idx_itr)
     return root
Ejemplo n.º 5
0
def sorted_array_to_bst(nums: list[int]) -> Optional[TreeNode]:
    if not nums:
        return None

    middle = len(nums) // 2
    root = TreeNode(nums[middle])
    root.left = sorted_array_to_bst(nums[:middle])
    root.right = sorted_array_to_bst(nums[middle + 1 :])
    return root
def build_tree(preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
    if not inorder:
        return None
    mid = inorder.index(preorder[0])
    root = TreeNode(preorder[0])
    if len(inorder) > 1:
        root.left = build_tree(preorder[1 : mid + 1], inorder[:mid])
        root.right = build_tree(preorder[mid + 1 :], inorder[mid + 1 :])
    return root
Ejemplo n.º 7
0
 def delete(self, root: TreeNode, num: int) -> TreeNode:
     if not root:
         return None
     if num == root.val:
         return None
     elif num < root.val:
         root.left = self.delete(root.left, num)
     else:
         root.right = self.delete(root.right, num)
     return root
Ejemplo n.º 8
0
 def sorted_array_to_bst(self, nums, start, stop):
     if start <= stop:
         # 这里 + 1 保证如果对称的时候,取偏右,因为题目中数组是中序遍历的
         mid = start + (stop - start + 1) // 2
         node = TreeNode(nums[mid])
         node.left = self.sorted_array_to_bst(nums, start, mid - 1)
         node.right = self.sorted_array_to_bst(nums, mid + 1, stop)
         return node
     else:
         return None
 def build_bst(start: int, end: int) -> Optional[TreeNode]:
     nonlocal head
     if start > end:
         return None
     middle = (start + end) // 2
     left = build_bst(start, middle - 1)
     root = TreeNode(head.val)
     root.left = left
     head = head.next
     root.right = build_bst(middle + 1, end)
     return root
Ejemplo n.º 10
0
Archivo: 701.py Proyecto: Cjz-Y/shuati
    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return TreeNode(val)

        if val > root.val:
            root.right = self.insertIntoBST(root.right, val)

        if val < root.val:
            root.left =  self.insertIntoBST(root.left, val)

        return root
    def __buildTree(self, preorder_itr, inorder):
        if not inorder:
            return None
        try:
            curpre = next(preorder_itr)
        except StopIteration:
            return None

        idx = inorder.index(curpre)
        root = TreeNode(curpre)
        root.left = self.__buildTree(preorder_itr, inorder[:idx])
        root.right = self.__buildTree(preorder_itr, inorder[idx + 1:])
        return root
Ejemplo n.º 12
0
Archivo: 701.py Proyecto: Cjz-Y/shuati
    def insertIntoBST11(self, root: TreeNode, val: int) -> TreeNode:
        self.bianli(root)
        i = 0
        for i in range(len(self.xl)):
            if val > self.xl[i].val:
                break

        if not self.xl[i].right:
            self.xl[i].right = TreeNode(val)
            return root

        if not self.xl[i + 1].left:
            self.xl[i + 1].left = TreeNode(val)
            return root
    def buildTree(self, preorder, inorder):
        m = len(preorder)
        n = len(inorder)
        if m != n:
            return None
        if m == 0:
            return None

        val = preorder[0]
        for i, v in enumerate(inorder):
            if v == val:
                break
        head = TreeNode(val)
        head.left = self.buildTree(preorder[1:i+1], inorder[0:i])
        head.right = self.buildTree(preorder[i+1:], inorder[i+1:])
        return head
Ejemplo n.º 14
0
    def helper(in_order: List[int],
               post_order: List[int]) -> Optional[TreeNode]:
        if in_order and post_order:
            root_val = post_order[-1]
            for root_offset, val in enumerate(in_order):
                if val == root_val:
                    break
            else:
                root_offset = 0

            root = TreeNode(root_val)
            root.left = helper(in_order[:root_offset],
                               post_order[:root_offset])
            root.right = helper(in_order[root_offset + 1:],
                                post_order[root_offset:-1])
            return root
    def buildTree(self, inorder, postorder):
        m = len(inorder)
        n = len(postorder)
        if m != n:
            return None
        if m == 0:
            return None

        val = postorder[-1]
        for i, v in enumerate(inorder):
            if v == val:
                break
        head = TreeNode(val)
        head.left = self.buildTree(inorder[0:i], postorder[0:i])
        head.right = self.buildTree(inorder[i+1:], postorder[i:-1])
        return head
Ejemplo n.º 16
0
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        """
        分析了一下,除了 root 可能有 right 其余的都是 left

        0
        算法不正确,原因在于题目要求的树是 DFS
        [-10,-3,0,5,9]
        5 是 9 的下一层,如果右侧按顺序,就成了 5 在 9 的上一层

        1
        分析发现,既然是 DF,相当于两树合并起来
        还是不对,理解错题目了,是要求平衡二叉树

        2
        感觉可以用索引来完成

        分析时间复杂度
        取切片时称动元素为基本操作
        1/2 n
            1/4 n
                1/8 n
                1/8 n
            1/4 n
                1/8 n
                1/8 n
        1/2 n
            ...

        可以看到每一轮共有 k 个 1/k n
        所以每一轮为 n
        而轮数为 log(n) 所以 T(n)=O(n logn)

        分析空间复杂度
        输出的树不考虑,那临时占用的就只有 mid 变量,与结点数一致
        S(n)=O(n)
        """
        if not nums:
            return None
        mid = len(nums) // 2
        root = TreeNode(nums[mid])
        # 原数组中序遍历而来,所以左右各能组成树
        if 0 < mid:
            root.left = self.sortedArrayToBST(nums[:mid])
        if mid + 1 < len(nums):
            root.right = self.sortedArrayToBST(nums[mid + 1:])
        return root
Ejemplo n.º 17
0
def is_balanced(root: TreeNode) -> bool:
    if not root:
        return True
    if not (is_balanced(root.left) and is_balanced(root.right)):
        return False
    left_height = root.left.val if root.left else 0
    right_height = root.right.val if root.right else 0
    root.val = max(left_height, right_height) + 1
    return -1 <= left_height - right_height <= 1
Ejemplo n.º 18
0
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        """
        分析了一下,除了 root 可能有 right 其余的都是 left

        0
        算法不正确,原因在于题目要求的树是 DFS
        [-10,-3,0,5,9]
        5 是 9 的下一层,如果右侧按顺序,就成了 5 在 9 的上一层

        1
        分析发现,既然是 DF,相当于两树合并起来
        还是不对,理解错题目了,是要求平衡二叉树
        """
        if not nums:
            return None
        mid = len(nums) // 2
        root = TreeNode(nums[mid])
        left = root
        for i in range(mid - 1, -1, -1):
            left.left = TreeNode(nums[i])
            left = left.left

        if len(nums) > 2:
            # 右侧树,从最后一个元倒退回去
            root.right = TreeNode(nums[-1])
            left = root.right
            for i in range(len(nums) - 2, mid, -1):
                left.left = TreeNode(nums[i])
                left = left.left
        return root
Ejemplo n.º 19
0
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        """
        分析了一下,除了 root 可能有 right 其余的都是 left

        0
        算法不正确,原因在于题目要求的树是 DF
        [-10,-3,0,5,9]
        5 是 9 的下一层,如果右侧按顺序,就成了 5 在 9 的上一层
        """
        if not nums:
            return None
        mid = len(nums) // 2
        root = TreeNode(nums[mid])
        left = root
        for i in range(mid - 1, -1, -1):
            left.left = TreeNode(nums[i])
            left = left.left
        right = root
        for i in range(mid + 1, len(nums)):
            right.right = TreeNode(nums[i])
            right = right.right
        return root
    def sortedListToBST(self, head):
        if not head:
            return None
        if not head.next:
            node = TreeNode(head.val)
            return node

        fast = head
        slow = head
        prev = None
        while fast.next and fast.next.next:
            fast = fast.next.next
            prev = slow
            slow = slow.next

        node = TreeNode(slow.val)
        right = slow.next
        if prev:
            prev.next = None
            node.left = self.sortedListToBST(head)
        else:
            node.left = self.sortedListToBST(None)
        node.right = self.sortedListToBST(right)
        return node
Ejemplo n.º 21
0
 def helper(self, ans: dict, pre: TreeNode, nums: List[int]):
     if not nums:
         tree = self.copy(pre)
         node_str = self.node_str(tree)
         if node_str not in ans:
             ans[node_str] = tree
     else:
         for i, num in enumerate(nums):
             nums.remove(num)
             if pre is None:
                 self.helper(ans, TreeNode(num), nums)
             else:
                 if self.insert(pre, num):  # 成功插入才继续
                     self.helper(ans, pre, nums)
                     self.delete(pre, num)
             nums.insert(i, num)
def insert_into_bst(root: TreeNode, val: int) -> TreeNode:
    node, prev, is_left = root, None, False
    while node:
        prev = node
        if val < node.val:
            node, is_left = node.left, True
        else:
            node, is_left = node.right, False

    new_node = TreeNode(val)
    if prev is None:
        return new_node

    if is_left:
        prev.left = new_node
    else:
        prev.right = new_node
    return root
Ejemplo n.º 23
0
def deserialize(data: str) -> Optional[TreeNode]:
    nodes = map(lambda t: None if t in ("null", "") else TreeNode(int(t)),
                data.split(","))
    root = next(nodes)
    if root is None:
        return None

    queue = deque([root])
    is_left = True
    node = None
    for next_node in nodes:
        if next_node:
            queue.append(next_node)
        if is_left:
            node = queue.popleft()
            node.left = next_node
        else:
            node.right = next_node
        is_left = not is_left
    return root
Ejemplo n.º 24
0
    def recoverTree(self, root: TreeNode) -> None:
        """
        前 100 中的最后一题,后续不会再按顺序刷了
        可能会解决自己感兴趣的题目,或者是练习某些 tag
        从7月1日第一题开始,马上就十一了,连续做了 3 个月的题,保证每天都有一题。
        虽然感觉有些难题自己还是思路不太好,但也聊胜于无,加油。

        回到这一题 0098 中的一些 trick 应该用不了,还是要老老实实判断当前结点下是否合法,不合法则找出应该和哪一个交换

        折腾了一会儿,还是做不出来
        >>> root=TreeNode.from_leetcode_array_str('[1,3,null,null,2]')
        >>> Solution().recoverTree(root)
        >>> root.to_leetcode_array_str()
        '[3,1,null,null,2]'
        """
        print(root.to_tree_graph())
        bad = self.find_bad(root, float('-inf'), float('inf'))
        if bad:
            node = bad[0]
            replace = self.replace(root, *bad[1:])
            node.val, replace.val = replace.val, node.val
Ejemplo n.º 25
0
def recover_tree(root: TreeNode) -> None:
    if not root:
        return

    prev = TreeNode(-(2 ** 31) - 1)
    first_error, second_error = None, None

    def inorder(node: TreeNode) -> None:
        nonlocal prev, first_error, second_error
        if node.left:
            inorder(node.left)
        if prev.val >= node.val and not first_error:
            first_error = prev
        if prev.val >= node.val and first_error:
            second_error = node
        prev = node
        if node.right:
            inorder(node.right)

    inorder(root)
    first_error.val, second_error.val = second_error.val, first_error.val
            return levels
        stack = [root]
        direction = 1
        while stack:
            level = []
            next_stack = []
            while stack:
                node = stack.pop()
                level.append(node.val)
                if direction == 1:
                    first = node.left
                    next = node.right
                else:
                    first = node.right
                    next = node.left
                if first:
                    next_stack.append(first)
                if next:
                    next_stack.append(next)
            direction ^= 1

            levels.append(level)
            stack = next_stack
        return levels

a = [3,9,20,'#','#',15,7]
a = [1,2,3,4, '#', '#', 5]
tree = TreeNode.from_list(a)
s = Solution()
print(s.zigzagLevelOrder(tree))
Ejemplo n.º 27
0
    while len(right) < n:
        right.append('')
    left = [_fill_width(i, width) for i in left]
    right = [_fill_width(i, width) for i in right]
    res = [_fill_width(parent, width * 2 + 4)]
    for l, r in zip(left, right):
        res.append(l + ' ' * 4 + r)
    return res


def _max_line_width(lines: List[str]) -> int:
    if not lines:
        return 0
    return len(max(lines, key=lambda x: len(x)))


def _fill_width(line: str, width: int) -> str:
    n = width - len(line)
    left = n // 2
    right = n - left
    return ' ' * left + line + ' ' * right


if __name__ == '__main__':
    from leetcode import TreeNode

    print(to_tree_graph(TreeNode.from_num(123456)))
    print(
        to_tree_graph(
            TreeNode.from_array([3, None, 30, 10, None, None, 15, None, 45])))
Ejemplo n.º 28
0
 def invert(node: TreeNode) -> None:
     node.left, node.right = node.right, node.left
     if node.left:
         invert(node.left)
     if node.right:
         invert(node.right)
Ejemplo n.º 29
0
 def test(self):
     tree = TreeNode.from_iter(range(1, 10))
     print(tree)
     print()
     morris_inorder_traversal(tree)
Ejemplo n.º 30
0
# Definition for a  binary tree node
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
from leetcode import TreeNode
class Solution:
    # @param root, a tree node
    # @return a boolean
    def isValidBST(self, root):
        return self.validBST(root, None, None)

    def validBST(self, root, Min, Max):
        if not root:
            return True
        if Min != None and Min >= root.val:
            return False
        if Max != None and Max <= root.val:
            return False
        return (self.validBST(root.left, Min, root.val) 
            and self.validBST(root.right, root.val, Max))

if __name__ == '__main__':
    root = TreeNode(0)
    root.right = TreeNode(-1)
    s = Solution()
    print s.isValidBST(root)