def deserialize(self, data): """Decodes your encoded data to tree. :type data: str :rtype: TreeNode """ if not data: return None data = deque(data.split(',')) root = TreeNode(int(data.popleft())) nextlevel = deque([root]) while data: level = nextlevel nextlevel = deque() while level and data: node = level.popleft() if not node: continue # Get left leftstr = data.popleft() leftval = int(leftstr) if leftstr != 'null' else None if leftval is not None: node.left = TreeNode(leftval) nextlevel.append(node.left) if data: # Get right rightstr = data.popleft() rightval = int(rightstr) if rightstr != 'null' else None if rightval is not None: node.right = TreeNode(rightval) nextlevel.append(node.right) return root
def create_bst_part(self, items: [], start, end): # Parent node will be a median of items im = math.floor(start + (end - start) / 2) node = TreeNode(items[im], None, None) # Recursive call to fill left/right children of BST if im > start: node.left = self.create_bst_part(items, start, im) if end > im + 1: node.right = self.create_bst_part(items, im, end) return node
def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode: if not root: return None if root.val < L: root = self.trimBST(root.right, L, R) elif root.val > R: root = self.trimBST(root.left, L, R) else: root.left = self.trimBST(root.left, L, R) root.right = self.trimBST(root.right, L, R) return root
def test_lowest_common_ancestor_example3(self): """ Example 3: Input: root = [1,2], p = 1, q = 2 Output: 1 """ res = LowestCommonAncestor().lowestCommonAncestor(root=TreeNode.of( [1, 2]), p=TreeNode(1), q=TreeNode(2)) self.assertEqual(1, res.val)
def test_right_side_view__allright(self): """ 1 <--- \ 2 <--- \ 3 <--- """ root = TreeNode(1, TreeNode(2, TreeNode(3))) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1, 2, 3], res)
def test_lowest_common_ancestor_example1(self): """ Example 1: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of nodes 5 and 1 is 3. """ res = LowestCommonAncestor().lowestCommonAncestor(root=TreeNode.of( [3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]), p=TreeNode(5), q=TreeNode(1)) self.assertEqual(3, res.val)
def test_lowest_common_ancestor_example2(self): """ Example 2: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. """ res = LowestCommonAncestor().lowestCommonAncestor(root=TreeNode.of( [3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]), p=TreeNode(5), q=TreeNode(4)) self.assertEqual(5, res.val)
def test_right_side_view__135(self): """ 1 <--- / \ 2 3 <--- \ 5 <--- """ root = TreeNode(1, TreeNode(2, None, TreeNode(5)), TreeNode(3)) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1, 3, 5], res)
def test_traverse__completed_tree(self): # 0.5, 1, 1.5, 2,3 tree = TreeNode(2, TreeNode(1, # root-left TreeNode(0.5), # root-left-left TreeNode(1.5) # root-left-right ), # Right TreeNode(3)) original = [2, 1, 0.5, 1.5, 3] self.assertListEqual(original, TreeTraversalPreOrder.traverse_iterative(tree)) self.assertListEqual(original, TreeTraversalPreOrder().traverse_recursive(tree))
def test_traverse__single_branch_tree(self): # 0.5, 1, 1.5, 2,3 tree = TreeNode(2, TreeNode(1, # root-left TreeNode(0.5), # root-left-left TreeNode(1.5) # root-left-right ), # Right None) original = [2, 1, 0.5, 1.5] self.assertListEqual(original, TreeTraversalPreOrder.traverse_iterative(tree)) self.assertListEqual(original, TreeTraversalPreOrder().traverse_recursive(tree))
def test_traverse__empty_left_branch(self): tree = TreeNode( 1, # root None, # root-left TreeNode( 2, # root-right TreeNode(3) # root-right-left )) original = [3, 2, 1] actual = TreeTraversalPostOrder.traverse_iterative(tree) self.assertListEqual(original, actual) self.assertListEqual(original, TreeTraversalPostOrder().traverse_recursive(tree))
def test_right_side_view__allleft(self): """ 1 <--- / \ 2 3 <--- / \ 0 5 <--- / -1 <--- """ root = TreeNode(1, None, TreeNode(2, None, TreeNode(3))) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1, 2, 3], res)
def test_is_subtree_example2(self): """ Example 2: Input: root = [3,4,5,1,2,null,null,0], subRoot = [4,1,2] Output: false """ self.assertFalse(SubtreeOfAnotherTree().isSubtree(root=TreeNode( 3, TreeNode(4, TreeNode(5), TreeNode(1, TreeNode(0), None)), TreeNode(2)), subRoot=TreeNode( 4, TreeNode(1), TreeNode(2))))
def test_traverse__single_node_tree(self): tree = TreeNode(1) original = [1] self.assertListEqual(original, TreeTraversalPostOrder.traverse_iterative(tree)) self.assertListEqual(original, TreeTraversalPostOrder().traverse_recursive(tree))
def test_is_subtree_example1(self): """ Example 1: Input: root = [3,4,5,1,2], subRoot = [4,1,2] Output: true """ self.assertTrue(SubtreeOfAnotherTree().isSubtree( root=TreeNode(3, TreeNode(4, TreeNode(1), TreeNode(2)), TreeNode(5)), subRoot=TreeNode(4, TreeNode(1), TreeNode(2))))
def test_trim_bst(self): tree = TreeNode(4, TreeNode(2, TreeNode(1), TreeNode(3)), TreeNode(6, TreeNode(5), TreeNode(7))) trimmed = TrimBST().trimBST(tree, 3, 5) self.assertEqual(trimmed.val, 4) self.assertEqual(trimmed.left.val, 3) self.assertEqual(trimmed.right.val, 5)
def test_trim_bst__bad_tree(self): # It is not a BST, but let's it to be trimmed tree = TreeNode(1, TreeNode(2, TreeNode(3), TreeNode(4)), TreeNode(5, TreeNode(6), TreeNode(7))) trimmed = TrimBST().trimBST(tree, 1, 2) self.assertEqual(trimmed.val, 1) self.assertEqual(trimmed.left.val, 2)
def test_max_path_sum__example1(self): """ Example 1: Input: root = [1,2,3] Output: 6 """ root = TreeNode.of([1, 2, 3]) res = BinaryTreeMaxPathSum().maxPathSum(root) self.assertEqual(6, res)
def test_max_path_sum__example2(self): """ Example 2: Input: root = [-10,9,20,null,null,15,7] Output: 42 """ root = TreeNode.of([-10, 9, 20, None, None, 15, 7]) res = BinaryTreeMaxPathSum().maxPathSum(root) self.assertEqual(42, res)
def test_serialize__example1(self): """ Example 1: 1 / \ 2 3 / \ 4 5 Input: root = [1,2,3,null,null,4,5] Output: [1,2,3,null,null,4,5] """ root = TreeNode(1, TreeNode(2), TreeNode(3, TreeNode(4), TreeNode(5))) out = SerDeBinaryTree().serialize(root) self.assertEqual("1,2,3,null,null,4,5", out)
def test_right_side_view__example1(self): """ Example: Input: [1,2,3,null,5,null,4] Output: [1, 3, 4] Explanation: 1 <--- / \ 2 3 <--- \ \ 5 4 <--- """ root = TreeNode(1, TreeNode(2, None, TreeNode(5)), TreeNode(3, None, TreeNode(4))) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1, 3, 4], res)
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: if not t1 and not t2: return None val = (t1.val if t1 else 0) + (t2.val if t2 else 0) left = self.mergeTrees( t1.left if t1 else None, t2.left if t2 else None) if (t1 and t1.left) or (t2 and t2.left) else None right = self.mergeTrees( t1.right if t1 else None, t2.right if t2 else None) if (t1 and t1.right) or (t2 and t2.right) else None return TreeNode(val, left, right)
def test_right_side_view__1(self): """ 1 <--- / \ 2 3 <--- \ 5 <--- """ root = TreeNode(1) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1], res)
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: """ Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. For example, given preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] Return the following binary tree: 3 / \ 9 20 / \ 15 7 """ if not preorder or not inorder: return None elif len(preorder) == len(inorder) == 1: return TreeNode(preorder[0]) # Root node val val = preorder[0] # Calculate left inorder, preorder and node leftinorder = inorder[:inorder.index(val)] leftpreorder = preorder[1:1 + len(leftinorder)] leftnode = self.buildTree(leftpreorder, leftinorder) # Calculate right inorder, preorder and node rightinorder = inorder[inorder.index(val)+1:] rightpreorder = preorder[1 + len(leftinorder):] rightnode = self.buildTree(rightpreorder, rightinorder) # Build a new node with left and right node = TreeNode(preorder[0], leftnode, rightnode) return node
def test_right_side_view__135neg1(self): """ 1 <--- / \ 2 3 <--- / \ 0 5 <--- / -1 <--- """ root = TreeNode(1, TreeNode(2, TreeNode(0, TreeNode(-1)), TreeNode(5)), TreeNode(3)) res = BinaryTreeRightSideView().rightSideView(root) self.assertEqual([1, 3, 5, -1], res)
def test_of(self): tree = TreeNode(1, # Left level1 TreeNode(2, # Level2 TreeNode(4, None, None), TreeNode(5, None, None)), # Right level1 TreeNode(3, # Level2 TreeNode(6, None, None), TreeNode(7, None, None))) # Get linked lists of depths according to quiz requirements res = ListOfDepth().of(tree) # Translate linked lists to list lst = self.as_list(res) self.assertListEqual(lst[0], [1]) self.assertListEqual(lst[1], [2, 3]) self.assertListEqual(lst[2], [4, 5, 6, 7])
def test_serialize_zeroes(self): out = SerDeBinaryTree().serialize(TreeNode(0, TreeNode(0), TreeNode(0))) self.assertEqual("0,0,0", out)
def test_serialize_single(self): out = SerDeBinaryTree().serialize(TreeNode(1)) self.assertEqual("1", out)
def test_is_subtree_121_1(self): self.assertFalse(SubtreeOfAnotherTree().isSubtree(root=TreeNode( 1, TreeNode(2, TreeNode(1))), subRoot=TreeNode(2)))
def test_is_subtree_11_1(self): self.assertTrue(SubtreeOfAnotherTree().isSubtree(root=TreeNode( 1, TreeNode(1)), subRoot=TreeNode(1)))