def deserialize(self, data):
        """Decodes your encoded data to tree.

        :type data: str
        :rtype: TreeNode
        """
        if data == '':
            return None

        data = list(map(lambda x: None if x == 'None' else int(x), data.split(',')))

        root = TreeNode(data[0])
        q = deque([root])
        idx = 1

        while idx < len(data):
            node = q.pop()
            left = data[idx]
            right = data[idx+1]
            idx += 2
            if left is not None:
                node.left = TreeNode(left)
                q.appendleft(node.left)
            if right is not None:
                node.right = TreeNode(right)
                q.appendleft(node.right)

        return root
 def helper(arr):
     if not arr:
         return None
     mid = len(arr) // 2
     rtn = TreeNode(arr[mid])
     rtn.left = helper(arr[:mid])
     rtn.right = helper(arr[mid + 1:])
     return rtn
 def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
     if not preorder:
         return None
     root = TreeNode(preorder[0])
     idx = inorder.index(preorder[0])
     root.left = self.buildTree(preorder[1:1 + idx], inorder[0:idx])
     root.right = self.buildTree(preorder[1 + idx:], inorder[idx + 1:])
     return root
Beispiel #4
0
 def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
     if root == None:
         return TreeNode(val)
     elif val < root.val:
         root.left = self.insertIntoBST(root.left, val)
     else:
         root.right = self.insertIntoBST(root.right, val)
     return root
 def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
     if not inorder:
         return None
     rtn = TreeNode(postorder[-1])
     idx = inorder.index(postorder[-1])
     rtn.left = self.buildTree(inorder[:idx], postorder[:idx])
     rtn.right = self.buildTree(inorder[idx + 1:],
                                postorder[idx:len(postorder) - 1])
     return rtn
Beispiel #6
0
 def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
     if root:
         if root.val < low:
             root = self.trimBST(root.right, low, high)
         elif root.val > high:
             root = self.trimBST(root.left, low, high)
         else:
             root.left = self.trimBST(root.left, low, high)
             root.right = self.trimBST(root.right, low, high)
     return root
Beispiel #7
0
    def rec(self, root, sum):
        if root is None:
            return (sum, None)

        total, r = self.rec(root.right, sum)
        new_root = TreeNode(root.val + total)
        new_total, l = self.rec(root.left, new_root.val)
        new_root.left = l
        new_root.right = r
        return (new_total, new_root)
Beispiel #8
0
 def traverse(tree):
     nonlocal ans, curr
     if not tree:
         return
     traverse(tree.left)
     if ans:
         curr.right = TreeNode(tree.val)
         curr = curr.right
     else:
         ans = curr = TreeNode(tree.val)
     traverse(tree.right)
Beispiel #9
0
 def helper(pre_tran, post_tran):
     if not pre_tran:
         return None
     ret = TreeNode(pre_tran[0])
     if len(pre_tran) > 1:
         right_root = post_tran[-2]
         right_idx = pre_tran.index(right_root)
         ret.left = helper(pre_tran[1:right_idx],
                           post_tran[:right_idx - 1])
         ret.right = helper(pre_tran[right_idx:],
                            post_tran[right_idx - 1:len(post_tran) - 1])
     return ret
Beispiel #10
0
 def helper(k):
     if k not in mem:
         rtn = []
         for i in range(1, k - 1, 2):
             for left in helper(i):
                 for right in helper(k - i - 1):
                     cur = TreeNode()
                     cur.left = left
                     cur.right = right
                     rtn.append(cur)
         mem[k] = rtn
     return mem[k]
 def addOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode:
     dummy = TreeNode(0, root)
     row = [dummy]
     for _ in range(depth - 1):
         row = [
             child for node in row for child in [node.left, node.right]
             if child
         ]
     for node in row:
         node.left = TreeNode(val, node.left, None)
         node.right = TreeNode(val, None, node.right)
     return dummy.left
 def build_tree(start, end):
     if start > end:
         return [None]
     rtn = []
     for cur_val in range(start, end + 1):
         cur_left = build_tree(start, cur_val - 1)
         cur_right = build_tree(cur_val + 1, end)
         for left in cur_left:
             for right in cur_right:
                 node = TreeNode(cur_val)
                 node.left = left
                 node.right = right
                 rtn.append(node)
     return rtn
Beispiel #13
0
 def sortedListToBST(self, head: ListNode) -> TreeNode:
     if not head:
         return None
     slow, fast = head, head
     pre = None
     while fast and fast.next:
         pre = slow
         slow = slow.next
         fast = fast.next.next
     if pre:
         pre.next = None
     rtn = TreeNode(slow.val)
     rtn.left = self.sortedListToBST(head) if head != slow else None
     rtn.right = self.sortedListToBST(slow.next)
     return rtn
 def inorder(node):
     nonlocal cur
     if node:
         inorder(node.left)
         cur.right = TreeNode(node.val)
         cur = cur.right
         inorder(node.right)
Beispiel #15
0
 def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
     if not root:
         return None
     if root.val == key:
         if not root.left:
             return root.right
         if not root.right:
             return root.left
         new_root = root.left
         while new_root.right:
             new_root = new_root.right
         root.val, new_root.val = new_root.val, root.val
         root.left = self.deleteNode(root.left, key)
     elif root.val > key:
         root.left = self.deleteNode(root.left, key)
     else:
         root.right = self.deleteNode(root.right, key)
     return root
        def mid_ord(node: TreeNode) -> int:
            nonlocal accu_sum
            if node is None:
                return

            mid_ord(node.right)
            accu_sum += node.val
            node.val = accu_sum
            mid_ord(node.left)
    def mergeTrees(self, t1, t2):
        """
        :type t1: TreeNode
        :type t2: TreeNode
        :rtype: TreeNode
        """

        if t1 is None and t2 is None:
            return None
        
        root = TreeNode(0)
        if t1:
            root.val += t1.val
        if t2:
            root.val += t2.val

        root.left = self.mergeTrees(t1.left if t1 else None, t2.left if t2 else None)
        root.right = self.mergeTrees(t1.right if t1 else None, t2.right if t2 else None)
        return root
Beispiel #18
0
 def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
     if not root:
         return root
     if root.val == key:
         if not root.left:
             return root.right
         elif not root.right:
             return root.left
         else:
             # Find successor
             succ = root.right
             while succ and succ.left:
                 succ = succ.left
             root.val = succ.val
             root.right = self.deleteNode(root.right, succ.val)
     elif key < root.val:
         root.left = self.deleteNode(root.left, key)
     else:
         root.right = self.deleteNode(root.right, key)
     return root
Beispiel #19
0
        def expan(node: TreeNode):
            if node.left is None and node.right is None:
                return node
            if node.left is None:
                return expan(node.right)
            if node.right is None:
                ltail = expan(node.left)
                node.right = node.left
                node.left = None
                return ltail
            
            ltail = expan(node.left)
            l = node.left
            r = node.right
            node.left = None
            node.right = l
            ltail.right = r

            rtail = expan(r)
            return rtail
Beispiel #20
0
        def traverse(post_beg, post_end, in_beg, in_end):
            if post_end <= post_beg:
                return None

            # Find the index of current root in inorder traversal list
            idx = inorder_indices[postorder[post_end - 1]]
            root = TreeNode(inorder[idx])

            # The portion of left subtree in the inorder list is given by [in_beg : idx]
            # The portion of right subtree in the inorder list is given by [idx + 1 : in_end]
            # The lengths of left and right are given by (idx - in_beg) and (in_end - idx)
            # Now we can obtain the portions of left and right subtree from the post order list:
            # Left subtree in the postorder list: [post_beg : idx]
            # Right subtree in the postorder list: [idx + 1 : in_end]

            # Construct both subtrees recursively
            root.left = traverse(post_beg, post_beg + idx - in_beg, in_beg,
                                 idx)
            root.right = traverse(post_end - in_end + idx, post_end - 1,
                                  idx + 1, in_end)
            return root
Beispiel #21
0
 def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
     if not root1 and not root2:
         return None
     new_tree = TreeNode(0)
     n1 = root1 if root1 else TreeNode(0)
     n2 = root2 if root2 else TreeNode(0)
     new_tree.val = n1.val + n2.val
     new_tree.left = self.mergeTrees(n1.left, n2.left)
     new_tree.right = self.mergeTrees(n1.right, n2.right)
     return new_tree
    def increasingBST(self, root: TreeNode) -> TreeNode:
        rtn = cur = TreeNode()

        def inorder(node):
            nonlocal cur
            if node:
                inorder(node.left)
                cur.right = TreeNode(node.val)
                cur = cur.right
                inorder(node.right)

        inorder(root)
        return rtn.right
Beispiel #23
0
    def allPossibleFBT(self, n: int) -> List[TreeNode]:
        mem = {
            1: [TreeNode()]
        }

        def helper(k):
            if k not in mem:
                rtn = []
                for i in range(1, k - 1, 2):
                    for left in helper(i):
                        for right in helper(k - i - 1):
                            cur = TreeNode()
                            cur.left = left
                            cur.right = right
                            rtn.append(cur)
                mem[k] = rtn
            return mem[k]

        return helper(n)
Beispiel #24
0
 def val2node(n: str):
     if n != 'None':
         return TreeNode(int(n))
     else:
         return None
Beispiel #25
0
# -*- coding: utf-8 -*-

# https://leetcode.com/problems/convert-bst-to-greater-tree/description/

from util import TreeNode


class Solution(object):
    def convertBST(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        return self.rec(root, 0)[1]

    def rec(self, root, sum):
        if root is None:
            return (sum, None)

        total, r = self.rec(root.right, sum)
        new_root = TreeNode(root.val + total)
        new_total, l = self.rec(root.left, new_root.val)
        new_root.left = l
        new_root.right = r
        return (new_total, new_root)


solution = Solution()
assert solution.convertBST(TreeNode.of([5, 2, 13])) == [18, 20, 13]
assert solution.convertBST(TreeNode.of([2, 0, 3, -4, 1])) == [5, 6, 3, 2, 6]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# https://leetcode.com/problems/diameter-of-binary-tree/description/

class Solution(object):
    def diameterOfBinaryTree(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """

        if root is None:
            return 0

        return self.inner(root)[0]-1
        
    def inner(self, root):
        """return (max_diameter, max_depth)"""
        if root is None:
            return (0, 0)

        l_diameter, l_depth = self.inner(root.left)
        r_diameter, r_depth = self.inner(root.right)
        return (max(l_diameter, r_diameter, l_depth+r_depth+1) , max(l_depth, r_depth)+1)

from util import TreeNode
solution = Solution()
assert solution.diameterOfBinaryTree(TreeNode.of([1,2,3,4,5])) == 3
Beispiel #27
0
        """

        if s is None and t is None:
            return True
        elif s is None or t is None:
            return False

        return self.equals(s, t) or self.isSubtree(
            s.left, t) or self.isSubtree(s.right, t)

    def equals(self, s, t):
        if s is None and t is None:
            return True
        elif s is None or t is None:
            return False

        return s.val == t.val and self.equals(s.left, t.left) and self.equals(
            s.right, t.right)


from util import TreeNode
solution = Solution()
assert solution.isSubtree(TreeNode.of([3, 4, 5, 1, 2]), TreeNode.of([4, 1, 2]))
assert not solution.isSubtree(TreeNode.of([3, 4, 5, 1, 2, None, None, 0]),
                              TreeNode.of([4, 1, 2]))
assert solution.isSubtree(
    TreeNode.of([
        1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None,
        1, None, 1, None, 1, 2
    ]), TreeNode.of([1, None, 1, None, 1, None, 1, None, 1, None, 1, 2]))
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# https://leetcode.com/problems/merge-two-binary-trees/description/

from util import TreeNode

class Solution(object):
    def mergeTrees(self, t1, t2):
        """
        :type t1: TreeNode
        :type t2: TreeNode
        :rtype: TreeNode
        """

        if t1 is None and t2 is None:
            return None
        
        root = TreeNode(0)
        if t1:
            root.val += t1.val
        if t2:
            root.val += t2.val

        root.left = self.mergeTrees(t1.left if t1 else None, t2.left if t2 else None)
        root.right = self.mergeTrees(t1.right if t1 else None, t2.right if t2 else None)
        return root

solution = Solution()
assert solution.mergeTrees(TreeNode.of([1,3,2,5]), TreeNode.of([2,1,3,None,4,None,7])) == [3,4,5,5,4,None,7]
Beispiel #29
0
        @lru_cache(None)
        def isLeaf(node: TreeNode):
            if node is None:
                return False
            return node.left is None and node.right is None

        def dfs(node: TreeNode):
            nonlocal ans
            if node is None:
                return
            if isLeaf(node.left):
                ans += node.left.val
                dfs(node.right)
                return
            dfs(node.left)
            dfs(node.right)

        dfs(root)
        return ans


# @lc code=end

t = TreeNode(2)
tt = TreeNode(1)
tt.left = t
s = Solution()
r = s.sumOfLeftLeaves(tt)
print(r)
Beispiel #30
0
# condition to optimize

from util import TreeNode


class Solution(object):
    def pathSum(self, root, sum):
        return self.inner(root, sum, 0, {0: 1})

    def inner(self, root, target, sofar, counts):
        if not root:
            return 0

        ret = 0
        complement = sofar + root.val - target
        if complement in counts:
            ret += counts[complement]

        sofar += root.val
        counts.setdefault(sofar, 0)  # consider root.val is 0, what happens?
        counts[sofar] += 1
        ret += self.inner(root.left, target, sofar, counts)
        ret += self.inner(root.right, target, sofar, counts)
        counts[sofar] -= 1
        return ret


solution = Solution()
assert solution.pathSum(
    TreeNode.of([10, 5, -3, 3, 2, None, 11, 3, -2, None, 1]), 8) == 3