# if not curr: # return False # left = recurse_tree(curr.left) # right = recurse_tree(curr.right) # # mid = curr == p or curr == q # if mid + left + right >= 2: # ans = curr # return mid or left or right # # ans = None # recurse_tree(root) # return ans def lca(root, p, q): if p.val <= root.val <= q.val or q.val <= root.val <= p.val: return root elif root.val > p.val and root.val > q.val: return lca(root.left, p, q) elif root.val < p.val and root.val < q.val: return lca(root.right, p, q) # t = binary_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) t = binary_tree([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) print(t) nodes = binary_tree_nodes(t) print(nodes) print(repr(lowest_common_ancestor(t, nodes[1], nodes[4]))) print(repr(lca(t, nodes[1], nodes[4])))
def has_path_sum(root, sum): def dfs(node, currsum): if node.left is None and node.right is None: if currsum == sum: return True if node.left and dfs(node.left, currsum + node.left.val): return True if node.right and dfs(node.right, currsum + node.right.val): return True return False if root is None: return False return dfs(root, root.val) # def hasPathSum(root, targetSum): # if root is None: # return False # # if not root.right and not root.left: # return root.val == targetSum # # return hasPathSum(root.left, targetSum - root.val) or hasPathSum(root.right, targetSum - root.val) t1 = binary_tree( [5, 4, 8, 11, None, 13, 4, 7, 2, None, None, None, None, None, 1]) print(t1) print(has_path_sum(t1, 22))
# return mincount # t1 = binary_tree([1, 2, None, 3, 4]) # print(t1) # print(min_camera_cover(t1)) # # t2 = binary_tree([1, 2, None, 3, None, None, None, 4, None, None, None, None, None, None, None, None, 5]) # print(t2) # print(min_camera_cover(t2)) # t3 = binary_tree([1, 2, None, 3, None, None, None, 4, None, None, None, None, None, None, None, None, 5]) # print(t3) # print(min_camera_cover(t3)) t = binary_tree( [1, None, 2, None, None, None, 3, None, None, None, None, None, None, None, 4, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 5, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 6, 7, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 8, 9, ]) print(t) print(min_camera_cover(t))
dfs(root, 0, sum) return count # def path_sum(root, sum): # def dfs(node, prefs, prefsum): # nonlocal count # prefsum += node.val # x = prefsum - sum # if x in prefs: # count += prefs[x] # if node.left or node.right: # prefs[prefsum] = prefs[prefsum] + 1 if prefsum in prefs else 1 # if node.left: # dfs(node.left, prefs, prefsum) # if node.right: # dfs(node.right, prefs, prefsum) # # if root is None: # return 0 # if root.left is None and root.right is None: # return 1 if root.val == sum else 0 # count = 0 # dfs(root, {}, 0) # return count t = binary_tree([10, 5, -3, 3, 2, None, 11, 3, -2, None, 1]) print(t) print(path_sum(t, 8))
if curr.right: if dfs(curr.right, seq + [curr.right.val]): return True return False return dfs(root, [root.val]) # def is_valid_sequence(root, arr): # def dfs(curr, seq): # if curr.left is None and curr.right is None: # is a leaf # if seq == arr: # return True # if curr.left: # if dfs(curr.left, seq + [curr.left.val]): # return True # if curr.right: # if dfs(curr.right, seq + [curr.right.val]): # return True # return False # # return dfs(root, [root.val]) t = binary_tree([0, 1, 0, 0, 1, 0, None, None, 1, 0, 0]) assert is_valid_sequence(t, [0, 1, 0, 1]) is True assert is_valid_sequence(t, [0, 1, 1, 0]) is True assert is_valid_sequence(t, [0, 0, 0]) is True assert is_valid_sequence(t, [0]) is False assert is_valid_sequence(t, [1]) is False assert is_valid_sequence(t, [0, 1, 1, 1]) is False
# And the value to search: 2 # # You should return this subtree: # # 2 # / \ # 1 3 # # In the example above, if we want to search the value 5, since there is no node with value 5, we should return NULL. # # Note that an empty tree is represented by NULL, therefore you would see the expected output (serialized tree # format) as [], not null. from BinaryTrees import binary_tree, print_preorder def search_bst(node, val): while node: if val == node.val: return node elif val < node.val: node = node.left else: node = node.right return None t = binary_tree([4, 2, 7, 1, 3]) print(t) print(search_bst(t, 2))
# preorder(node.left, lvl + 1) # if node.right is not None: # preorder(node.right, lvl + 1) # # if root is None: # return 0 # maxlvl = 0 # preorder(root, 0) # return maxlvl def max_leaf_depth(root): if root is None: return 0 left = right = 0 if root.left: left = 1 + max_leaf_depth(root.left) if root.right: right = 1 + max_leaf_depth(root.right) return max(left, right) if __name__ == '__main__': t = binary_tree([3, 9, 20, None, None, 15, 7]) print(t) print(max_leaf_depth(t)) t = binary_tree([1]) print(t) print(max_leaf_depth(t))
# no extra space required def flatten(root): """ Do not return anything, modify root in-place instead. """ if root is None: return root nodes = [] curr = root stack = [curr] while stack: curr = stack.pop() nodes.append(curr) if curr.right: stack.append(curr.right) if curr.left: stack.append(curr.left) print(nodes) for i in range(len(nodes) - 1): nodes[i].left = None nodes[i].right = nodes[i + 1] return root t = binary_tree([1, 2, 5, 3, 4, None, 6]) t = binary_tree([1, 2, 5, 3, 4]) print(t) print(flatten(t)) # print not working on level 6
# def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right from collections import deque from BinaryTreeLevelOrderTraversal import level_order from BinaryTrees import binary_tree def deepest_leaves_sum(root): q = deque([root]) while q: lsum = 0 for _ in range(len(q)): node = q.popleft() lsum += node.val if node.left: q.append(node.left) if node.right: q.append(node.right) return lsum # arr = [3, 9, 20, None, None, 15, 7] arr = [1, 2, 3, 4, 5, None, 6, 7, None, None, None, None, None, None, 8] t = binary_tree(arr) print(t) print(level_order(t)) print(deepest_leaves_sum(t))
def merge_trees(t1, t2): if t1 is None: return t2 if t2 is None: return t1 t = TreeNode(t1.val + t2.val) t.left = merge_trees(t1.left, t2.left) t.right = merge_trees(t1.right, t2.right) return t # O(k) space # def merge_trees(t1, t2): # if t1 is None: # return t2 # if t2 is None: # return t1 # t1.val += t2.val # t1.left = merge_trees(t1.left, t2.left) # t1.right = merge_trees(t1.right, t2.right) # return t1 t1 = binary_tree([1, 3, 2, 5]) print(t1) t2 = binary_tree([2, 1, 3, None, 4, None, 7]) print(t2) print(merge_trees(t1, t2))
# queue = deque([arr[0]]) # lvls = [] # # while queue: # lvls.append([]) # count = len(queue) # for _ in range(count): # node = queue.popleft() # lvls[-1].append(node.val) # if node.left: # queue.append(node.left) # if node.right: # queue.append(node.right) # return lvls arr = [4, 2, 6, 1, 3, 5, 7] # level-order # for vals in gen_subtrees(arr): # t = binary_tree(vals) # print(t) for vals in gen_subtrees2(arr): t = binary_tree(vals) print(t) # print(len(gen_subtrees2(arr))) # print(gen_subtrees2([1, 2, 3, 4, 5])) # print(gen_subtrees2([1, 2, 3, 4])) # print(gen_subtrees2([1, 2, 3, 4, 5])) # print(gen_subtrees2([1, 2, 3, 4, 5, 6, 7]))
from BinaryTrees import binary_tree def binary_tree_all_paths(node): def dfs(node, path): if len(path) > 1: paths.append(path) if node.left: dfs(node.left, path + [node.left.val]) if node.right: dfs(node.right, path + [node.right.val]) if node is None: return 0 paths = [] stack = [node] while stack: node = stack.pop() dfs(node, [node.val]) if node.right: stack.append(node.right) if node.left: stack.append(node.left) return paths t = binary_tree([1, 2, 3, 4, 5, 6, 7]) print(t) print(binary_tree_all_paths(t))
nonlocal maxd left = right = 0 if node.left: left = 1 + height(node.left) if node.right: right = 1 + height(node.right) maxd = max(maxd, left + right) return max(left, right) maxd = 0 height(node) return maxd # def diameterOfBinaryTree(self, root): # self.ans = 1 # # def depth(node): # if not node: return 0 # L = depth(node.left) # R = depth(node.right) # self.ans = max(self.ans, L + R + 1) # return max(L, R) + 1 # # depth(root) # return self.ans - 1 if __name__ == '__main__': t = binary_tree([1, 2, 3, 4, 5]) assert diameter(t) == 3
dfs(node.right, f'{path}->{node.right.val}') if node is None: return [] paths = [] dfs(node, str(node.val)) return paths def binary_tree_paths_bfs(node): if node is None: return [] paths = [] q = deque([(node, str(node.val))]) while q: node, path = q.popleft() if node.left is None and node.right is None: paths.append(path) if node.left: q.append((node.left, f'{path}->{node.left.val}')) if node.right: q.append((node.right, f'{path}->{node.right.val}')) return paths # t = binary_tree([1, 2, 3, 4, 5, 6, 7]) t = binary_tree([3, 1, 4, None, 2, None, 5]) print(t) print(binary_tree_paths(t)) print(binary_tree_paths_bfs(t))
# print(lvlarr) if set(q) == {None}: # q contains all Nones break if lvlarr[-1] is None: return False return True # t = binary_tree([1]) # t = binary_tree([]) # t = binary_tree([1, 2, 3, 4, 5, 6, 7]) # print(t) # print(level_order(t)) for i in range(1, 9): t = binary_tree([n for n in range(1, i)]) # print(t) # print(tree_is_complete(t)) assert tree_is_complete(t) is True t = binary_tree([1, None, 2]) assert tree_is_complete(t) is False t = binary_tree([1, 2, 3, None, 5]) assert tree_is_complete(t) is False t = binary_tree([1, 2, 3, 4, None, 6]) assert tree_is_complete(t) is False t = binary_tree([1, 2, 3, 4, 5, None, 7]) assert tree_is_complete(t) is False t = binary_tree([1, 2, None, 4, 5]) assert tree_is_complete(t) is False
# # max_single = max(max(l, r) + root.val, root.val) # max_top = max(max_single, l + r + root.val) # # find_max_util.res = max(find_max_util.res, max_top) # return max_single from BinaryTrees import binary_tree def max_path_sum(root): def find_max(root): nonlocal maxsum if root is None: return 0 maxl = find_max(root.left) maxr = find_max(root.right) max_root = max(maxl + root.val, maxr + root.val, root.val) maxsum = max(maxsum, max_root, maxl + maxr + root.val) return max_root maxsum = -sys.maxsize find_max(root) return maxsum t = binary_tree([-10, 9, 20, None, None, 15, 7]) print(t) print(max_path_sum(t))
# 4 # / \ # 2 7 # / \ / \ # 1 3 6 9 # # Output: # # 4 # / \ # 7 2 # / \ / \ # 9 6 3 1 from BinaryTrees import binary_tree def invert_tree(root): if root is None: return root if root.left: invert_tree(root.left) if root.right: invert_tree(root.right) root.left, root.right = root.right, root.left return root t = binary_tree([4, 2, 7, 1, 3, 6, 9]) print(t) print(invert_tree(t))
# retval = curr.val # return True # inord += 1 # if curr.right: # if inorder(curr.right): # return True # # inord = 1 # retval = None # inorder(root) # return retval def kth_smallest(curr, k): stack = [] while stack or curr: if curr: stack.append(curr) curr = curr.left else: curr = stack.pop() k -= 1 if k == 0: return curr.val curr = curr.right t = binary_tree([5, 3, 6, 2, 4, None, None, 1]) print(t) print(kth_smallest(t, 3))
lvl = -1 # lvlorder = [] evenamt = 0 oddamt = 0 while queue: lvl += 1 # lvlorder.append([]) for _ in range(len(queue)): node = queue.popleft() # lvlorder[-1].append(node.val) if lvl % 2 == 0: evenamt += node.val else: oddamt += node.val if node.left: queue.append(node.left) if node.right: queue.append(node.right) print(evenamt, oddamt) return max(evenamt, oddamt) # t = binary_tree([4, 2, 6, 1, 3, 5, 7]) # t = binary_tree([3, 2, 3, None, 3, None, 1]) # t = binary_tree([3, 4, 5, 1, 3, None, 1]) t = binary_tree([4, 1, None, 2, None, None, None, 3]) print(t) print(rob(t))
lvl = -1 q = deque([root]) while q: lvl += 1 for _ in range(len(q)): curr = q.popleft() if curr.left is None and curr.right is None: return lvl if curr.left: q.append(curr.left) if curr.right: q.append(curr.right) return 0 if __name__ == '__main__': t = binary_tree([3, 9, 20, None, None, 15, 7]) print(t) print(min_leaf_depth(t)) t = binary_tree([ 2, None, 3, None, None, None, 4, None, None, None, None, None, None, None, 5 ]) print(t) print(min_leaf_depth(t)) t = binary_tree([2, 0, 1]) print(t) print(min_leaf_depth(t))