:type q: TreeNode :rtype: TreeNode """ if p.val > root.val < q.val: return self.lowestCommonAncestor(root.right, p, q) elif p.val < root.val > q.val: return self.lowestCommonAncestor(root.left, p, q) else: #either p or q is root.val, or p and q on two sides return root # iterative - same idea. # assume p and q always exist def lowestCommonAncestor2(self, root, p, q): while root: if p.val > root.val < q.val: root = root.right elif p.val < root.val > q.val: root = root.left else: return root # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test root = build_tree_from_list([6, 2, 8, 0, 4, 7, 9, None, None, 3, 5]) print(Solution().lowestCommonAncestor(root, TreeNode(3), TreeNode(7)).val) print(Solution().lowestCommonAncestor2(root, TreeNode(3), TreeNode(7)).val)
if root: res.append(root.val) helper(root.left) helper(root.right) res = [] helper(root) return res # generic iterative traversal def preorderTraversal2(self, root): res, stack = [], [(root, False)] while stack: node, visited = stack.pop() if node: if not visited: # append in reversed order stack.append((node.right, False)) stack.append((node.left, False)) stack.append((node, True)) else: res.append(node.val) return res # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test root = build_tree_from_list([1,None,2,3,None]) print(Solution().preorderTraversal(root)) print(Solution().preorderTraversal2(root))
''' # Definition for a binary tree node # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # @param A : root node of tree # @return an integer def isBalanced(self, root): def depth(root): return 1 + max(depth(root.left), depth(root.right)) if root else 0 isbal = self.isBalanced if not root: return True depth_diff = abs(depth(root.left) - depth(root.right)) return depth_diff <= 1 and isbal(root.left) and isbal(root.right) # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().isBalanced(build_tree_from_list([1, 2, 3]))) print(Solution().isBalanced(build_tree_from_list([3, 2, None, 1])))
class Solution: # inplace - swap left and right child and resursive invert left and right def invertTree(self, root): """ :type root: TreeNode :rtype: TreeNode """ if root: root.left, root.right = root.right, root.left self.invertTree(root.left) self.invertTree(root.right) return root # inplace - one liner def invertTree2(self, root): invert = self.invertTree2 if root: root.left, root.right = invert(root.right), invert(root.left) return root # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list, serialize_tree_to_array # test root = build_tree_from_list([4, 2, 7, 1, 3, 6, 9]) print(serialize_tree_to_array(Solution().invertTree(root))) root = build_tree_from_list([4, 2, 7, 1, 3, 6, 9]) print(serialize_tree_to_array(Solution().invertTree2(root)))
if leaf ] return res[::-1] # bfs def levelOrderBottom2(self, root): from collections import deque queue = deque([root]) res = [] while queue: level = [] for _ in range(len(queue)): node = queue.popleft() if node: level.append(node.val) queue.append(node.left) queue.append(node.right) if level: res.append(level) return res[::-1] # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test root = build_tree_from_list([3, 9, 20, None, None, 15, 7]) print(Solution().levelOrderBottom2(root)) print(Solution().levelOrderBottom2(root))
class Solution: # pass variable by reference using class variable self. # allow -ve node. def maxPathSum(self, root): # returns the maximum sum of the path that can be extended to input # node's parent. def get_max_sum(node): if not node: return 0 # if path sum of a child is negative, ignore the child. left_sum = max(0, get_max_sum(node.left)) right_sum = max(0, get_max_sum(node.right)) # update the max_sum as we traverse through each node self.max_sum = max(self.max_sum, left_sum + right_sum + node.val) # only return the max of left or right as we cannot traverse both return max(left_sum, right_sum) + node.val # either use self.max_sum or non-primative type [] to pass by reference self.max_sum = float('-inf') get_max_sum(root) return self.max_sum # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().maxPathSum(build_tree_from_list([1, 2, 3]))) print(Solution().maxPathSum(build_tree_from_list([1, -2, 3])))
while pval not in parent or qval not in parent: if not stack: return -1 node = stack.pop() if node.left: parent[node.left.val] = node.val stack.append(node.left) if node.right: parent[node.right.val] = node.val stack.append(node.right) p_path = set() while pval: p_path.add(pval) pval = parent[pval] while qval not in p_path: qval = parent[qval] return qval # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test root = build_tree_from_list([3,5,1,6,2,0,8,None,None,7,4]) p = root.left.left q = root.left.right.right print(Solution().lowestCommonAncestor(root, p, q).val) print(Solution().lowestCommonAncestor2(root, p, q).val) print(Solution().lowestCommonAncestor2(root, p, q).val) print(Solution().lca(root, 6, 4))
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def isSymmetric(self, root): # resursively compare left child and right child def isMirror(L, R): if L and R and L.val == R.val: return isMirror(L.left, R.right) and isMirror(L.right, R.left) elif L == R == None: return True else: return False return isMirror(root, root) # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, 3, 4, 4, 3]))) print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, None, 3, None, 3]))) print(Solution().isSymmetric(build_tree_from_list([1, 2, 2, None, 3, 3, None])))
res = None for val in in_order(root): if not k: break res, k = val, k - 1 return res # same idea without using generator def kthSmallest2(self, root, k): def helper(root): if root and self.k: helper(root.left) self.res = root.val self.k -= 1 helper(root.right) self.res = None # use self to pass primative by reference self.k = k # use self to pass primative by reference helper(root) return self.res # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test root = build_tree_from_list([2, 1, 3]) print(Solution().kthSmallest(root, 2)) print(Solution().kthSmallest2(root, 2))
1 / 2 max depth = 2. ''' # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def maxDepth(self, root): """ :type root: TreeNode :rtype: int """ depth = self.maxDepth return 1 + max(depth(root.left), depth(root.right)) if root else 0 # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().maxDepth(build_tree_from_list([1, 2, None]))) print(Solution().maxDepth(build_tree_from_list([3, 9, 20, None, None, 15, 7])))
# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def minDepth(self, root): """ :type root: TreeNode :rtype: int """ if not root: return 0 elif not root.left: return 1 + self.minDepth(root.right) elif not root.right: return 1 + self.minDepth(root.left) else: # both right and left child exist return 1 + min(self.minDepth(root.left), self.minDepth(root.right)) # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().minDepth(build_tree_from_list([1]))) print(Solution().minDepth(build_tree_from_list([1, 2]))) print(Solution().minDepth(build_tree_from_list([1, 2, 3, 4, 5]))) print(Solution().minDepth(build_tree_from_list([1, 2, 3, 4, 5, 6])))
cur.left, cur.right = None, cur.left self.flatten(cur.right) # cur.left is always empty # iterative & inplace - same idea but traverse to the right def flatten2(self, root): cur = root while cur: if cur.left: # find the inorder predecesoor of curent node pre = cur.left while pre.right: pre = pre.right # pre is the inorder predecesoor pre.right = cur.right cur.left, cur.right = None, cur.left cur = cur.right # cur.left is always empty # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list, serialize_tree_to_array # test root = build_tree_from_list([1, 2, 5, 3, 4, None, 6]) Solution().flatten(root) print(serialize_tree_to_array(root)) root = build_tree_from_list([1, 2, 5, 3, 4, None, 6]) Solution().flatten2(root) print(serialize_tree_to_array(root))
# BFS search def zigzagLevelOrder2(self, root): from collections import deque queue, res = deque([root]), [] while queue: level = [] for _ in range(len(queue)): node = queue.popleft() if node: level.append(node.val) queue.append(node.left) queue.append(node.right) if len(res) % 2 != 0: level = level[::-1] if level: res.append(level) return res # import import sys, os sys.path.insert(0, os.path.abspath((os.pardir + os.sep) * 2 + 'mylib')) from BinaryTreeTraversalGenerator import TreeNode, build_tree_from_list # test print(Solution().zigzagLevelOrder( build_tree_from_list([3, 9, 20, None, None, 15, 7]))) print(Solution().zigzagLevelOrder2( build_tree_from_list([3, 9, 20, None, None, 15, 7]))) print(Solution().zigzagLevelOrder(build_tree_from_list([]))) print(Solution().zigzagLevelOrder2(build_tree_from_list([])))