return None nodes, index = data.split(' '), 1 root = TreeNode(int(nodes[0])) from queue import Queue q = Queue() q.put(root) while not q.empty() and index < len(nodes): node = q.get() if node is None: continue if index < len(nodes): left_node = TreeNode(int( nodes[index])) if nodes[index] != '#' else None node.left = left_node q.put(left_node) if index + 1 < len(nodes): right_node = TreeNode(int( nodes[index + 1])) if nodes[index + 1] != '#' else None node.right = right_node q.put(right_node) index += 2 return root if __name__ == '__main__': codec = Codec() print( codec.deserialize( codec.serialize( TreeNode.list2Tree([5, 2, 3, None, None, 2, 4, 3, 1]))))
from common import TreeNode class Solution: def levelOrder(self, root): if not root: return [] res = [] p = [root] while p: vals = [] next_floor_node = [] for node in p: vals.append(node.val) if node.left: next_floor_node.append(node.left) if node.right: next_floor_node.append(node.right) res.append(vals) p = next_floor_node return res if __name__ == '__main__': solution = Solution() print(solution.levelOrder(TreeNode.list2Tree([3, 9, 20, None, None, 15, 7])))
from common import TreeNode class Solution(object): def lowestCommonAncestor(self, root, p, q): if not root: return None if p is root or q is root or p.val < root.val < q.val or q.val < root.val < p.val: return root if max(p.val, q.val) < root.val: return self.lowestCommonAncestor(root.left, p, q) if min(p.val, q.val) > root.val: return self.lowestCommonAncestor(root.right, p, q) if __name__ == '__main__': solution = Solution() tree = TreeNode.list2Tree([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) print(solution.lowestCommonAncestor(tree, tree.right, tree.left.right.left).val)
from common import TreeNode class Solution: def flatten(self, root): if not root: return self.f(root) def f(self, node): tail, left_subtree, right_subtree = node, node.left, node.right if left_subtree: left_subtree = self.f(left_subtree) tail.right = left_subtree while tail.right: tail = tail.right if right_subtree: right_subtree = self.f(right_subtree) tail.right = right_subtree node.left = None return node if __name__ == '__main__': solution = Solution() tree = TreeNode.list2Tree([1, 2, 5, 3, 4, None, 6]) solution.f(tree) print(tree)
from common import TreeNode class Solution: def hasPathSum(self, root, sum): self.sum = sum return self.f(root, 0) def f(self, node, sum): if not node: return False if not node.left and not node.right: return sum + node.val == self.sum return self.f(node.left, sum + node.val) or self.f( node.right, sum + node.val) if __name__ == '__main__': solution = Solution() print( solution.hasPathSum( TreeNode.list2Tree( [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, 1]), 22))
from common import TreeNode class Solution: def inorderTraversal(self, root): return self.f(root) def f(self, node: TreeNode): if node is None: return [] print(node.val) return self.f(node.left) + [node.val] + self.f(node.right) if __name__ == '__main__': solution = Solution() print(solution.inorderTraversal(TreeNode.list2Tree([1, None, 2, 3])))
from common import TreeNode class Solution: def isBalanced(self, root): return self.helper(root)[0] if root else True def helper(self, node): if not node.left and not node.right: return True, 1 is_left_balanced, left_height = True, 0 if node.left: is_left_balanced, left_height = self.helper(node.left) is_right_balanced, right_height = True, 0 if is_left_balanced and node.right: is_right_balanced, right_height = self.helper(node.right) return is_left_balanced and is_right_balanced and abs(left_height - right_height) <= 1, 1 + max(left_height, right_height) if __name__ == '__main__': solution = Solution() print(solution.isBalanced(TreeNode.list2Tree([1, None, 2, None, 3])))
from common import TreeNode class Solution: def leafSimilar(self, root1, root2): return self.helper(root1) == self.helper(root2) def helper(self, node): if not node.left and not node.right: return (node.val, ) return (self.helper(node.left) if node.left else ()) + (self.helper(node.right) if node.right else ()) if __name__ == "__main__": solution = Solution() print( solution.leafSimilar( TreeNode.list2Tree([18, 35, 22, None, 103, 43, 101, 58, None, 97]), TreeNode.list2Tree([94, 102, 17, 122, None, None, 54, 58, 101, 97])))
from common import TreeNode class Solution: def increasingBST(self, root): res, _ = self.helper(root) if root else (root, None) return res def helper(self, node): left_head = left_tail = right_head = right_tail = node if node.left: left_head, left_tail = self.helper(node.left) left_tail.right = node if node.right: right_head, right_tail = self.helper(node.right) node.right = right_head node.left = None return left_head, right_tail if __name__ == "__main__": solution = Solution() print( solution.increasingBST( TreeNode.list2Tree( [5, 3, 6, 2, 4, None, 8, 1, None, None, None, 7, 9])))
from common import TreeNode class Solution: def findDuplicateSubtrees(self, root): self.pre_orders = set() self.res = {} self.f(root) return list(self.res.values()) def f(self, node): if not node: return None pre_order = (self.f(node.left), node.val, self.f(node.right)) if pre_order in self.pre_orders: self.res[pre_order] = node else: self.pre_orders.add(pre_order) return pre_order if __name__ == '__main__': solution = Solution() print( solution.findDuplicateSubtrees( TreeNode.list2Tree([1, 2, 3, 4, None, 2, 4, None, None, 4]))) print( solution.findDuplicateSubtrees( TreeNode.list2Tree( [0, 0, 0, 0, None, None, 0, None, None, None, 0])))
from common import TreeNode class Solution: def rob(self, root): if not root: return 0 return max(self.f(root)) def f(self, node): if not node.left and not node.right: return (0, node.val) left = self.f(node.left) if node.left else (0, 0) right = self.f(node.right) if node.right else (0, 0) return max([left[i] + right[j] for i in (0, 1) for j in (0, 1)]), node.val + left[0] + right[0] if __name__ == '__main__': solution = Solution() print(solution.rob(TreeNode.list2Tree([3, 2, 3, None, 3, None, 1]))) print(solution.rob(TreeNode.list2Tree([3, 4, 5, 1, 3, None, 1])))
from common import TreeNode class Solution: def insertIntoBST(self, root, val): self.helper(root, val) return root def helper(self, node, val): if node is None: return TreeNode(val) if val > node.val: node.right = self.helper(node.right, val) else: node.left = self.helper(node.left, val) return node if __name__ == "__main__": solution = Solution() print(solution.insertIntoBST(TreeNode.list2Tree([4, 2, 7, 1, 3]), 5))
from common import TreeNode class Solution: def pathSum(self, root, sum): if not root: return [] self.sum = sum self.res = [] self.f(root, root.val, (root.val, )) return self.res def f(self, node, cur_sum, path): if cur_sum == self.sum and not node.left and not node.right: self.res.append(path) return if node.left: self.f(node.left, cur_sum + node.left.val, (*path, node.left.val)) if node.right: self.f(node.right, cur_sum + node.right.val, (*path, node.right.val)) if __name__ == '__main__': solution = Solution() print(solution.pathSum(TreeNode.list2Tree([-2, None, -3]), -5))
from common import TreeNode class Solution: def isValidBST(self, root): return self.f(root)[0] def f(self, node, d=0): if node is None: return True, None left_result, left_max = self.f(node.left, -1) right_result, right_min = self.f(node.right, 1) res, p = node.val, node while d < 0 and p.right: p = p.right while d > 0 and p.left: p = p.left return left_result and right_result and (not left_max or left_max < node.val) \ and (not right_min or right_min > node.val), p.val if __name__ == '__main__': solution = Solution() print(solution.isValidBST(TreeNode.list2Tree([3,None,30,10,None,None,15,None,45])))
for node in f: if node.left: tmp_f.append(node.left) if node.right: tmp_f.append(node.right) f = tmp_f def insert(self, v): n = len(self.l) self.l.append(TreeNode(v)) if self.root: parent = self.l[(n - 1) // 2] if n & 1: parent.left = self.l[-1] else: parent.right = self.l[-1] return parent.val else: self.root = self.l[-1] return None def get_root(self): return self.root if __name__ == "__main__": cbtInserter = CBTInserter(TreeNode.list2Tree([1, 2, 3, 4, 5, 6])) print(cbtInserter.insert(7)) print(cbtInserter.insert(8)) print(cbtInserter.get_root())
q, depth = Queue(), float('-inf') q.put((root, 1)) while not q.empty(): node, cur_depth = q.get() depth = max(depth, cur_depth) if node.left: q.put((node.left, cur_depth + 1)) if node.right: q.put((node.right, cur_depth + 1)) col = 0 for _ in range(depth): col = 2 * col + 1 res = [[''] * col for _ in range(depth)] q.put((root, 0, 0, col - 1)) while not q.empty(): node, depth, lo, hi = q.get() mid = (lo + hi) // 2 res[depth][mid] = str(node.val) if node.left: q.put((node.left, depth + 1, lo, mid - 1)) if node.right: q.put((node.right, depth + 1, mid + 1, hi)) return res if __name__ == '__main__': solution = Solution() print(solution.printTree(TreeNode.list2Tree([1, 2, None]))) print(solution.printTree(TreeNode.list2Tree([1, 2, 3, None, 4]))) print(solution.printTree(TreeNode.list2Tree([1, 2, 5, 3, None, None, None, 4])))
from common import TreeNode class Solution: def sumNumbers(self, root): self.result = 0 if root: self.f(root, root.val) return self.result def f(self, node, num): if node.left is None and node.right is None: self.result += num return if node.left: self.f(node.left, num * 10 + node.left.val) if node.right: self.f(node.right, num * 10 + node.right.val) if __name__ == '__main__': solution = Solution() print(solution.sumNumbers(TreeNode.list2Tree([1, None, 3])))
return root if left and right else left or right def lowestCommonAncestorOnline(self, root, p, q): self.nodes, self.depth = [], [] self.dfs(root, 0) p_pos, q_pos = self.nodes.index(p), self.nodes.index(q) min_n, min_pos = float('inf'), 0 for i in range(min(p_pos, q_pos), max(p_pos, q_pos)): if self.depth[i] < min_n: min_n, min_pos = self.depth[i], i return self.nodes[min_pos] def dfs(self, node, depth): self.nodes.append(node) self.depth.append(depth) if node.left: self.dfs(node.left, depth + 1) if node.left or node.right: self.nodes.append(node) self.depth.append(depth) if node.right: self.dfs(node.right, depth + 1) if __name__ == '__main__': solution = Solution() tree = TreeNode.list2Tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) print( solution.lowestCommonAncestorOnline(tree, tree.right.left, tree.right.right))
from common import TreeNode class Solution: def minDepth(self, root): if not root: return 0 f, floor = [root], 0 while f: floor += 1 next = [] for node in f: if not node.left and not node.right: return floor if node.left: next.append(node.left) if node.right: next.append(node.right) f = next if __name__ == '__main__': solution = Solution() print(solution.minDepth(TreeNode.list2Tree([3, 9, 20, None, None, 15, 7])))
from common import TreeNode class Solution: def invertTree(self, root): if not root: return None root.left, root.right = self.invertTree(root.right), self.invertTree( root.left) return root if __name__ == '__main__': solution = Solution() print(solution.invertTree(TreeNode.list2Tree([4, 2, 7, 1, 3, 6, 9])))
from common import TreeNode class Solution: def zigzagLevelOrder(self, root): if not root: return [] res = [] p = [root] while p: vals = [] next_floor_node = [] for node in p: vals.append(node.val) if node.left: next_floor_node.append(node.left) if node.right: next_floor_node.append(node.right) res.append(vals) p = next_floor_node return [ seq[::-1] if index % 2 else seq for index, seq in enumerate(res) ] if __name__ == '__main__': solution = Solution() print( solution.zigzagLevelOrder( TreeNode.list2Tree([3, 9, 20, None, None, 15, 7])))
from common import TreeNode class Solution: def countNodes(self, root): if not root: return 0 from queue import Queue res, q = 0, Queue() q.put(root) while not q.empty(): node = q.get() res += 1 if node.left: q.put(node.left) if node.right: q.put(node.right) return res if __name__ == '__main__': solution = Solution() print(solution.countNodes(TreeNode.list2Tree([1, 2])))
from common import TreeNode class Solution: def subtreeWithAllDeepest(self, root): node, _ = self.helper(root, 1) return node def helper(self, node, depth): if not node: return None, float("-inf") if not node.left and not node.right: return node, depth left, left_depth = self.helper(node.left, depth + 1) right, right_depth = self.helper(node.right, depth + 1) if right_depth > left_depth: return right, right_depth elif left_depth > right_depth: return left, left_depth else: return node, left_depth if __name__ == "__main__": solution = Solution() print( solution.subtreeWithAllDeepest(TreeNode.list2Tree([0, 1, 3, None, 2])))
return (None, left_l + 1 + right_l) if not res else (res, None) def kthSmallest1(self, root, k): self.k = k self.start = False return self.f1(root).val def f1(self, node): res = None if node.left: res = self.f(node.left) elif not self.start: self.start = True if self.start: if not res and self.k == 1: res = node else: self.k -= 1 if not res and node.right: res = self.f(node.right) return res if __name__ == '__main__': solution = Solution() print( solution.kthSmallest( TreeNode.list2Tree( [5, 3, 9, 2, 4, 7, 10, 1, None, None, None, 6, 8, None, 11]), 11))
class Solution: def maxPathSum(self, root): return max(self.f(root)) def f(self, node): if not node.left and not node.right: return node.val, node.val left1, left2 = float('-inf'), float('-inf') if node.left: left1, left2 = self.f(node.left) right1, right2 = float('-inf'), float('-inf') if node.right: right1, right2 = self.f(node.right) n = float('-inf') if node.left and left2 > 0 and node.right and right2 > 0: n = node.val + left2 + right2 return max(n, left1, left2, right1, right2), max(node.val + left2, node.val + right2, node.val) if __name__ == '__main__': solution = Solution() print(solution.maxPathSum(TreeNode.list2Tree([-3]))) print( solution.maxPathSum(TreeNode.list2Tree([-10, 9, 20, None, None, 15, 7]))) print( solution.maxPathSum( TreeNode.list2Tree( [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, 1])))
from common import TreeNode class Solution: def recoverTree(self, root): self.first, self.second, self.pre = None, None, None def traverse(node): if not node: return traverse(node.left) if self.pre and self.pre.val >= node.val: if not self.first: self.first = self.pre self.second = node self.pre = node traverse(node.right) traverse(root) self.first.val, self.second.val = self.second.val, self.first.val if __name__ == '__main__': solution = Solution() root = TreeNode.list2Tree([3, 4, 1, 5, 2]) solution.recoverTree(root) print(root)
start = min(start, 2 * index) end = max(end, 2 * index) q.put((node.left, depth + 1, 2 * index)) if node.right: start = min(start, 2 * index + 1) end = max(end, 2 * index + 1) q.put((node.right, depth + 1, 2 * index + 1)) width[depth + 1] = [start, end] return max([end - start + 1 for start, end in width.values()], default=0) if __name__ == '__main__': solution = Solution() print( solution.widthOfBinaryTree(TreeNode.list2Tree([1, 3, 2, 5, 3, None, 9]))) print(solution.widthOfBinaryTree(TreeNode.list2Tree([1, 3, None, 5, 3]))) print(solution.widthOfBinaryTree(TreeNode.list2Tree([1, 3, 2, 5, None]))) print( solution.widthOfBinaryTree( TreeNode.list2Tree([1, 3, 2, 5, None, None, 9, 6, None, None, 7]))) print( solution.widthOfBinaryTree( TreeNode.list2Tree([ 1, 5, 8, 9, 7, 7, 8, 1, 4, 8, 1, 9, 0, 8, 7, 1, 7, 4, 2, 9, 8, 2, 4, None, None, 9, None, None, None, 6, 0, 9, 4, 1, 0, 1, 8, 9, 0, 1, 8, 9, 1, 0, 9, 6, 2, 5, None, 2, 3, 0, 2, 4, 8, 8, 8, 5, 0, 0, 9, 4, 9, 1, None, 0, 7, 2, 2, 3, None, 6, 1, 0, 8, 9, 9, 9, 4, 8, 4, 3, 4, 4, 0, None, None, 8, 3, 8, None, None, 0, None, 0, 4, 9, 1, 2, None, 4, 4, 0, 4, 3, 5, 5, 7, 4, 1, 6, None, 1, 0, None, None, None, 2, 8, 7, 7, None, None, 0, 2, 5,
from common import TreeNode class Solution: def longestUnivaluePath(self, root): return max(self.dfs(root)) - 1 if root else 0 def dfs(self, node): if not node.left and not node.right: return 1, 1 l1, l2 = 0, 0 if node.left: l1, l2 = self.dfs(node.left) r1, r2 = 0, 0 if node.right: r1, r2 = self.dfs(node.right) l, r = l1 if node.left and node.val == node.left.val else 0, r1 if node.right and node.val == node.right.val else 0 return max(l + 1, r + 1), max(l1, r1, l2, r2, l + 1 + r) if __name__ == '__main__': solution = Solution() print(solution.longestUnivaluePath(TreeNode.list2Tree([5, 4, 5, 1, 1, 5])))
from common import TreeNode class Solution: def isSymmetric(self, root): return self.f(root, root) def f(self, node1, node2): if not node1 and not node2: return True if (not node1 and node2) or (node1 and not node2): return False return node1.val == node2.val and self.f( node1.left, node2.right) and self.f(node1.right, node2.left) if __name__ == '__main__': solution = Solution() print(solution.isSymmetric(TreeNode.list2Tree([1, 2, 2, None, 3, None, 3])))
from common import TreeNode class Solution: def pruneTree(self, root): if not self.f(root): return None return root def f(self, node): if node is None: return False left, right = self.f(node.left), self.f(node.right) if not left: node.left = None if not right: node.right = None return node.val == 1 or left or right if __name__ == '__main__': solution = Solution() print(solution.pruneTree(TreeNode.list2Tree([1, 1, 0, 1, 1, 0, 1, 0])))