def cloneTree(root: TreeNode) -> TreeNode: if root: newRoot = TreeNode(root.val) newRoot.left = cloneTree(root.left) newRoot.right = cloneTree(root.right) return newRoot return None
def convertBSTImpl(root: TreeNode, v: int) -> (TreeNode, int): if not root: return None, 0 newRight, sumRight = convertBSTImpl(root.right, v) newRoot = TreeNode(root.val + sumRight + v) newLeft, sumLeft = convertBSTImpl(root.left, newRoot.val) newRoot.left = newLeft newRoot.right = newRight return newRoot, sumLeft + root.val + sumRight
def sortedArrayToBSTImpl(nums: List[int], l, r: int): cnt = r - l if cnt == 0: return None if cnt == 1: return TreeNode(nums[l]) m = l + cnt // 2 return TreeNode(nums[m], sortedArrayToBSTImpl(nums, l, m), sortedArrayToBSTImpl(nums, m + 1, r))
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode: if not root: return None if root.val > high: return self.trimBST(root.left, low, high) if root.val < low: return self.trimBST(root.right, low, high) root.left = self.trimBST(root.left, low, high) root.right = self.trimBST(root.right, low, high) return root
def helper(beg: int, end: int) -> TreeNode: if beg > end: return None mid = beg + (end - beg) // 2 left = helper(beg, mid - 1) root = TreeNode(self.head.val) self.head = self.head.next root.left = left root.right = helper(mid + 1, end) return root
def impl(pre_b: int, pre_e: int, in_b: int, in_e: int) -> TreeNode: if pre_b == pre_e: return None val = preorder[pre_b] root = TreeNode(val) m = inorder_index[val] left_end = pre_b + 1 + m - in_b root.left = impl(pre_b + 1, left_end, in_b, m) root.right = impl(left_end, pre_e, m + 1, in_e) return root
def impl(root: TreeNode) -> TreeNode: if not root: return None left_end = impl(root.left) right_end = impl(root.right) right = root.right root.right = root.left root.left = None if left_end: left_end.right = right else: root.right = right if right_end: return right_end if left_end: return left_end return root
def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode: fakeRoot = TreeNode(0) current = [[root, fakeRoot, 1]] depth = 1 while depth < d: next_level = [] for n, p, _ in current: if n: next_level.append([n.left, n, 1]) next_level.append([n.right, n, 2]) depth += 1 current = next_level for n, p, x in current: if p: if x == 1: p.left = TreeNode(v, n) elif x == 2: p.right = TreeNode(v, None, n) return root if d > 1 else fakeRoot.left
if root is None: return 0 dl = dr = 0 if root.left: dl = self.minDepth(root.left) if root.right: dr = self.minDepth(root.right) if dl > 0 and dr > 0: return 1 + min(dl, dr) if dl > 0: return dl + 1 return dr + 1 tree1 = TreeNode(3) tree1.left = TreeNode(9) tree1.right = TreeNode(20) tree1.right.left = TreeNode(15) tree1.right.right = TreeNode(7) tree2 = TreeNode(1) tree2.left = TreeNode(2) tests = [(tree1, 2), (tree2, 2)] run_functional_tests(Solution().minDepth, tests)
L = solve(root.left) R = solve(root.right) dp0 = L[1] + R[1] dp1 = min(L[2] + min(R[1:]), R[2] + min(L[1:])) dp2 = 1 + min(L[:]) + min(R[:]) return [dp0, dp1, dp2] return min(solve(root)[1:]) tests = [ [ TreeNode(0, TreeNode(0, TreeNode(0), TreeNode(0))), 1 ], [ TreeNode(0, TreeNode(0, TreeNode(0, TreeNode(0, null, TreeNode(0))))), 2 ], [ TreeNode(0), 1
class Solution: def subtreeWithAllDeepest(self, root: TreeNode) -> TreeNode: def dfs(root: TreeNode) -> (TreeNode, int): if root is None: return root, 0 L = dfs(root.left) R = dfs(root.right) if L[1] > R[1]: return L[0], L[1] + 1 if R[1] > L[1]: return R[0], R[1] + 1 return root, L[1] + 1 return dfs(root)[0] root = TreeNode(3) root.left = TreeNode(5) root.left.left = TreeNode(6) root.left.right = TreeNode(2) root.left.right.left = TreeNode(7) root.left.right.right = TreeNode(4) root.right = TreeNode(1) root.right.left = TreeNode(0) root.right.right = TreeNode(8) tests = [(root, TreeNode(2, TreeNode(7), TreeNode(4)))] run_functional_tests(Solution().subtreeWithAllDeepest, tests)
def rightSideView(self, root: TreeNode) -> List[int]: levels = [] def rightSideViewImpl(root: TreeNode, level: int): if not root: return nonlocal levels if level == len(levels): levels.append(root.val) rightSideViewImpl(root.right, level+1) rightSideViewImpl(root.left, level + 1) rightSideViewImpl(root, 0) return levels root1 = TreeNode(1) root1.left = TreeNode(2) root1.right = TreeNode(3) root1.left.right = TreeNode(5) root1.right.right = TreeNode(4) tests = [ (root1, [1, 3, 4]) ] run_functional_tests(Solution().rightSideView, tests)
class Solution: def bstToGst(self, root: TreeNode) -> TreeNode: def convertBSTImpl(root: TreeNode, v: int) -> (TreeNode, int): if not root: return None, 0 newRight, sumRight = convertBSTImpl(root.right, v) newRoot = TreeNode(root.val + sumRight + v) newLeft, sumLeft = convertBSTImpl(root.left, newRoot.val) newRoot.left = newLeft newRoot.right = newRight return newRoot, sumLeft + root.val + sumRight return convertBSTImpl(root, 0)[0] root1 = TreeNode(4) root1.left = TreeNode(1) root1.right = TreeNode(6) root1.left.left = TreeNode(0) root1.left.right = TreeNode(2) root1.left.right.right = TreeNode(3) root1.right.left = TreeNode(5) root1.right.right = TreeNode(7) root1.right.right.right = TreeNode(8) """ 30 (36 (36 () 35 (33 ())
# Runtime: 32 ms, faster than 80.06% of Python3 online submissions for Binary Tree Level Order Traversal. # Memory Usage: 15.2 MB, less than 12.67% of Python3 online submissions for Binary Tree Level Order Traversal. class Solution: def levelOrder(self, root: TreeNode) -> List[List[int]]: levels = [] def traverse(root: TreeNode, level: int): nonlocal levels if not root: return if level >= len(levels): levels.append([]) levels[level].append(root.val) traverse(root.left, level + 1) traverse(root.right, level + 1) traverse(root, 0) return levels tests = [[ TreeNode(1, TreeNode(2, TreeNode(4), TreeNode(5)), TreeNode(3)), [[1], [2, 3], [4, 5]] ], [ TreeNode(3, TreeNode(9), TreeNode(20, TreeNode(15), TreeNode(7))), [[3], [9, 20], [15, 7]] ], [TreeNode(1), [[1]]], [null, []]] run_functional_tests(Solution().levelOrder, tests)
class Solution: def getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode: if not original: return None if original is target: return cloned resultLeft = self.getTargetCopy(original.left, cloned.left, target) if resultLeft: return resultLeft return self.getTargetCopy(original.right, cloned.right, target) root1 = TreeNode(7) root1.left = TreeNode(4) root1.right = TreeNode(3) root1.right.left = TreeNode(6) root1.right.right = TreeNode(19) print(Solution().getTargetCopy(root1, cloneTree(root1), root1.right).val) # 3 root2 = TreeNode(7) print(Solution().getTargetCopy(root2, cloneTree(root2), root2).val) # 7 root3 = TreeNode(8) root3.right = TreeNode(6) root3.right.right = TreeNode(5) root3.right.right.right = TreeNode(4)
""" prev, first, second = None, None, None def inorder(node: TreeNode): nonlocal prev, first, second if node.left: inorder(node.left) if not first and (not prev or node.val < prev.val): first = prev if first and (not prev or node.val < prev.val): second = node prev = node if node.right: inorder(node.right) inorder(root) first.val, second.val = second.val, first.val tests = [[ TreeNode(1, TreeNode(3, null, TreeNode(2))), TreeNode(3, TreeNode(1, null, TreeNode(2))) ], [ TreeNode(3, TreeNode(1), TreeNode(4, TreeNode(2))), TreeNode(2, TreeNode(1), TreeNode(4, TreeNode(3))) ]] run_functional_tests(in_place_to_function(Solution().recoverTree), tests)
class Solution: def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode: if not root: return None if root.val > high: return self.trimBST(root.left, low, high) if root.val < low: return self.trimBST(root.right, low, high) root.left = self.trimBST(root.left, low, high) root.right = self.trimBST(root.right, low, high) return root tests = [ (TreeNode(1, TreeNode(0), TreeNode(2)), 1, 2, TreeNode(1, None, TreeNode(2))), (TreeNode(3, TreeNode(0, None, TreeNode(2, TreeNode(1))), TreeNode(4)), 1, 3, TreeNode(3, TreeNode(2, TreeNode(1)))), ] def treesEqual(root1: TreeNode, root2: TreeNode) -> bool: if not root1 and not root2: return True if not root1 or not root2: return False if root1.val != root2.val: return False if not treesEqual(root1.left, root2.left): return False return treesEqual(root1.right, root2.right)
self.move_first() def next(self) -> int: value = self.current.val self.move_next() return value def hasNext(self) -> bool: return self.current is not None # Your BSTIterator object will be instantiated and called as such: # obj = BSTIterator(root) # param_1 = obj.next() # param_2 = obj.hasNext() root = TreeNode(5) root.left = TreeNode(3) root.left.right = TreeNode(4) root.left.left = TreeNode(2) root.right = TreeNode(7) root.right.left = TreeNode(6) # it = BSTIterator(root) # # while it.hasNext(): # print(it.next()) tests = [ ( ["BSTIterator", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next", "hasNext"], [[root], [], [], [], [], [], [], [], [], [], [], null, null, null],
""" class Solution: def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: if p is None and q is None: return True if p is None or q is None: return False if p.val != q.val: return False return self.isSameTree(p.left, q.left) and self.isSameTree( p.right, q.right) tree1 = TreeNode(1) tree1.left = TreeNode(2) tree1.right = TreeNode(3) tree2 = TreeNode(1) tree2.left = TreeNode(2) tree2.right = TreeNode(3) print(Solution().isSameTree(tree1, tree2)) # True tree1 = TreeNode(1) tree1.left = TreeNode(2) tree2 = TreeNode(1) tree2.right = TreeNode(2)
next_level.append([n.right, n, 2]) depth += 1 current = next_level for n, p, x in current: if p: if x == 1: p.left = TreeNode(v, n) elif x == 2: p.right = TreeNode(v, None, n) return root if d > 1 else fakeRoot.left tests = [(TreeNode(1, TreeNode(2, TreeNode(4)), TreeNode(3)), 5, 4, TreeNode(1, TreeNode(2, TreeNode(4, TreeNode(5), TreeNode(5))), TreeNode(3))), ( TreeNode(4, TreeNode(2, TreeNode(3), TreeNode(1)), TreeNode(6, TreeNode(5))), 1, 1, TreeNode( 1, TreeNode(4, TreeNode(2, TreeNode(3), TreeNode(1)), TreeNode(6, TreeNode(5)))), ), ( TreeNode(4, TreeNode(2, TreeNode(3), TreeNode(1)), TreeNode(6, TreeNode(5))),
# self.i = 0 # # def dfs(node): # if node: # if node.val != voyage[self.i]: # self.flipped = [-1] # return # self.i += 1 # if self.i < len(voyage) and node.left and node.left.val != voyage[self.i]: # self.flipped.append(node.val) # dfs(node.right) # dfs(node.left) # else: # dfs(node.left) # dfs(node.right) # # dfs(root) # if self.flipped and self.flipped[0] == -1: # self.flipped = [-1] # return self.flipped tests = [((TreeNode(1, TreeNode(5, TreeNode(7), TreeNode(2)), TreeNode(6, TreeNode(4), TreeNode(3)))), [1, 5, 2, 6, 3, 4, 7], [-1]), (TreeNode(2, TreeNode(1, TreeNode(4), TreeNode(3))), [2, 1, 3, 4], [1]), (TreeNode(1, TreeNode(2)), [2, 1], [-1]), (TreeNode(1, TreeNode(2), TreeNode(3)), [1, 3, 2], [1]), (TreeNode(1, TreeNode(2), TreeNode(3)), [1, 2, 3], [])] run_functional_tests(Solution().flipMatchVoyage, tests)
nodes.append(current.val) if not current.left and not current.right: if len(nodes) <= 1: result += 1 dfs(current.left) dfs(current.right) if current.val in nodes: nodes.remove(current.val) else: nodes.append(current.val) dfs(root) return result root1 = TreeNode(2) root1.left = TreeNode(3) root1.left.left = TreeNode(3) root1.left.right = TreeNode(1) root1.right = TreeNode(1) root1.right.right = TreeNode(1) # if Solution().pseudoPalindromicPaths(root1) == 2: # print("PASS") # else: # print("FAIL") root2 = TreeNode(2) root2.left = TreeNode(1) root2.left.left = TreeNode(1) root2.left.right = TreeNode(3)
def averageOfLevels(self, root: TreeNode) -> List[float]: levels = [] def walkLevels(root: TreeNode, level: int): if not root: return nonlocal levels if len(levels) <= level: levels.append([root.val, 1]) else: levels[level][0] += root.val levels[level][1] += 1 walkLevels(root.left, level + 1) walkLevels(root.right, level + 1) walkLevels(root, 0) return [s / c for s, c in levels] root1 = TreeNode(3) root1.left = TreeNode(9) root1.right = TreeNode(20) root1.right.left = TreeNode(15) root1.right.right = TreeNode(7) tests = [(root1, [3, 14.5, 11])] run_functional_tests(Solution().averageOfLevels, tests)
path2: List[TreeNode] = self.getPath(root, q) n1 = len(path1) n2 = len(path2) i1 = n1 - 1 i2 = n2 - 1 while i2 > i1: i2 -= 1 while i1 > i2: i1 -= 1 while path1[i1] is not path2[i2]: i1 -= 1 i2 -= 1 return path2[i1] t1 = TreeNode(6) n1 = t1.left = TreeNode(2) n2 = t1.right = TreeNode(8) t1.left.left = TreeNode(0) n3 = t1.left.right = TreeNode(4) t1.left.right.left = TreeNode(3) t1.left.right.right = TreeNode(5) t1.right.left = TreeNode(7) t1.right.right = TreeNode(9) print(Solution().lowestCommonAncestor(t1, n1, n2).val) # 6 print(Solution().lowestCommonAncestor(t1, n1, n3).val) # 2
class Solution: @staticmethod def isLeave(root: TreeNode): return root.left is None and root.right is None def sumOfLeftLeavesImpl(self, root: TreeNode, isLeft: bool) -> int: if Solution.isLeave(root): return root.val if isLeft else 0 sumleft = sumright = 0 if root.left: sumleft = self.sumOfLeftLeavesImpl(root.left, True) if root.right: sumright = self.sumOfLeftLeavesImpl(root.right, False) return sumleft + sumright def sumOfLeftLeaves(self, root: TreeNode) -> int: if root is None: return 0 return self.sumOfLeftLeavesImpl(root, False) t1 = TreeNode(3) t1.left = TreeNode(9) t1.right = TreeNode(20) t1.right.left = TreeNode(15) t1.right.right = TreeNode(7) print(Solution().sumOfLeftLeaves(t1)) # 24
cache: SortedDict[int, SortedDict[int, List[int]]] = {} self.verticalTraversalImpl(cache, root, 0, 0) result: List[List[int]] = [] for d in sorted(cache): result.append([]) for s in sorted(cache[d]): for v in sorted(cache[d][s]): result[-1].append(v) return result # [0,2,1,3,null,null,null,4,5,null,7,6,null,10,8,11,9] root1 = TreeNode(3) root1.left = TreeNode(9) root1.right = TreeNode(20) root1.right.left = TreeNode(15) root1.right.right = TreeNode(7) root2 = TreeNode(1) root2.left = TreeNode(2) root2.left.left = TreeNode(4) root2.left.right = TreeNode(5) root2.right = TreeNode(3) root2.right.left = TreeNode(6) root2.right.right = TreeNode(7) tests = [ (root1, [[9],[3,15],[20],[7]]),
# Memory Usage: 18.8 MB, less than 5.07% of Python3 online submissions for Convert BST to Greater Tree. from Common.Leetcode import TreeNode from Common.TreeUtils import printTree class Solution: def convertBST(self, root: TreeNode) -> TreeNode: def convertBSTImpl(root: TreeNode, v: int) -> (TreeNode, int): if not root: return None, 0 newRight, sumRight = convertBSTImpl(root.right, v) newRoot = TreeNode(root.val + sumRight + v) newLeft, sumLeft = convertBSTImpl(root.left, newRoot.val) newRoot.left = newLeft newRoot.right = newRight return newRoot, sumLeft + root.val + sumRight return convertBSTImpl(root, 0)[0] root1 = TreeNode(4) root1.left = TreeNode(1) root1.right = TreeNode(6) root1.left.left = TreeNode(0) root1.left.right = TreeNode(2) root1.left.right.right = TreeNode(3) root1.right.left = TreeNode(5) root1.right.right = TreeNode(7) root1.right.right.right = TreeNode(8) printTree(Solution().convertBST(root1))
class Solution: def binaryTreePaths(self, root: TreeNode) -> List[str]: def binaryTreePathsImpl(root: TreeNode, result: List[str], path: str): if root is None: return newpath: str = path if len(newpath) > 0: newpath += "->" newpath += str(root.val) if root.left is None and root.right is None: result.append(newpath) else: if root.left is not None: binaryTreePathsImpl(root.left, result, newpath) if root.right is not None: binaryTreePathsImpl(root.right, result, newpath) result: List[str] = [] binaryTreePathsImpl(root, result, "") return result t1 = TreeNode(1) t1.left = TreeNode(2) t1.left.right = TreeNode(5) t1.right = TreeNode(3) tests = [(t1, ['1->2->5', '1->3'])] run_functional_tests(Solution().binaryTreePaths, tests)
""" Runtime: 40 ms, faster than 89.58% of Python3 online submissions for Path Sum. Memory Usage: 15.4 MB, less than 98.89% of Python3 online submissions for Path Sum. """ class Solution: def hasPathSum(self, root: TreeNode, sum: int) -> bool: if root is None: return False if root.left is None and root.right is None: return sum == root.val if self.hasPathSum(root.left, sum - root.val): return True return self.hasPathSum(root.right, sum - root.val) t1 = TreeNode(5) t1.left = TreeNode(4) t1.right = TreeNode(8) t1.left.left = TreeNode(11) t1.left.left.left = TreeNode(7) t1.left.left.right = TreeNode(2) t1.right.left = TreeNode(13) t1.right.right = TreeNode(4) t1.right.right.right = TreeNode(1) tests = [ (t1, 22, True) ]
right_end = impl(root.right) right = root.right root.right = root.left root.left = None if left_end: left_end.right = right else: root.right = right if right_end: return right_end if left_end: return left_end return root return impl(root) tests = [[ TreeNode(1, TreeNode(2, TreeNode(3), TreeNode(4)), TreeNode(5, null, TreeNode(6))), TreeNode( 1, null, TreeNode( 2, null, TreeNode(3, null, TreeNode(4, null, TreeNode(5, null, TreeNode(6)))))) ], [null, null], [TreeNode(0), TreeNode(0)]] run_functional_tests(make_inplace(Solution().flatten), tests)