def deserialize(self, data): """Decodes your encoded data to tree. :type data: str :rtype: TreeNode """ if data == '': return None data = list(map(lambda x: None if x == 'None' else int(x), data.split(','))) root = TreeNode(data[0]) q = deque([root]) idx = 1 while idx < len(data): node = q.pop() left = data[idx] right = data[idx+1] idx += 2 if left is not None: node.left = TreeNode(left) q.appendleft(node.left) if right is not None: node.right = TreeNode(right) q.appendleft(node.right) return root
def helper(arr): if not arr: return None mid = len(arr) // 2 rtn = TreeNode(arr[mid]) rtn.left = helper(arr[:mid]) rtn.right = helper(arr[mid + 1:]) return rtn
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: if not preorder: return None root = TreeNode(preorder[0]) idx = inorder.index(preorder[0]) root.left = self.buildTree(preorder[1:1 + idx], inorder[0:idx]) root.right = self.buildTree(preorder[1 + idx:], inorder[idx + 1:]) return root
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: if root == None: return TreeNode(val) elif val < root.val: root.left = self.insertIntoBST(root.left, val) else: root.right = self.insertIntoBST(root.right, val) return root
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode: if not inorder: return None rtn = TreeNode(postorder[-1]) idx = inorder.index(postorder[-1]) rtn.left = self.buildTree(inorder[:idx], postorder[:idx]) rtn.right = self.buildTree(inorder[idx + 1:], postorder[idx:len(postorder) - 1]) return rtn
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode: if root: if root.val < low: root = self.trimBST(root.right, low, high) elif root.val > high: root = self.trimBST(root.left, low, high) else: root.left = self.trimBST(root.left, low, high) root.right = self.trimBST(root.right, low, high) return root
def rec(self, root, sum): if root is None: return (sum, None) total, r = self.rec(root.right, sum) new_root = TreeNode(root.val + total) new_total, l = self.rec(root.left, new_root.val) new_root.left = l new_root.right = r return (new_total, new_root)
def traverse(tree): nonlocal ans, curr if not tree: return traverse(tree.left) if ans: curr.right = TreeNode(tree.val) curr = curr.right else: ans = curr = TreeNode(tree.val) traverse(tree.right)
def helper(pre_tran, post_tran): if not pre_tran: return None ret = TreeNode(pre_tran[0]) if len(pre_tran) > 1: right_root = post_tran[-2] right_idx = pre_tran.index(right_root) ret.left = helper(pre_tran[1:right_idx], post_tran[:right_idx - 1]) ret.right = helper(pre_tran[right_idx:], post_tran[right_idx - 1:len(post_tran) - 1]) return ret
def helper(k): if k not in mem: rtn = [] for i in range(1, k - 1, 2): for left in helper(i): for right in helper(k - i - 1): cur = TreeNode() cur.left = left cur.right = right rtn.append(cur) mem[k] = rtn return mem[k]
def addOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode: dummy = TreeNode(0, root) row = [dummy] for _ in range(depth - 1): row = [ child for node in row for child in [node.left, node.right] if child ] for node in row: node.left = TreeNode(val, node.left, None) node.right = TreeNode(val, None, node.right) return dummy.left
def build_tree(start, end): if start > end: return [None] rtn = [] for cur_val in range(start, end + 1): cur_left = build_tree(start, cur_val - 1) cur_right = build_tree(cur_val + 1, end) for left in cur_left: for right in cur_right: node = TreeNode(cur_val) node.left = left node.right = right rtn.append(node) return rtn
def sortedListToBST(self, head: ListNode) -> TreeNode: if not head: return None slow, fast = head, head pre = None while fast and fast.next: pre = slow slow = slow.next fast = fast.next.next if pre: pre.next = None rtn = TreeNode(slow.val) rtn.left = self.sortedListToBST(head) if head != slow else None rtn.right = self.sortedListToBST(slow.next) return rtn
def inorder(node): nonlocal cur if node: inorder(node.left) cur.right = TreeNode(node.val) cur = cur.right inorder(node.right)
def deleteNode(self, root: TreeNode, key: int) -> TreeNode: if not root: return None if root.val == key: if not root.left: return root.right if not root.right: return root.left new_root = root.left while new_root.right: new_root = new_root.right root.val, new_root.val = new_root.val, root.val root.left = self.deleteNode(root.left, key) elif root.val > key: root.left = self.deleteNode(root.left, key) else: root.right = self.deleteNode(root.right, key) return root
def mid_ord(node: TreeNode) -> int: nonlocal accu_sum if node is None: return mid_ord(node.right) accu_sum += node.val node.val = accu_sum mid_ord(node.left)
def mergeTrees(self, t1, t2): """ :type t1: TreeNode :type t2: TreeNode :rtype: TreeNode """ if t1 is None and t2 is None: return None root = TreeNode(0) if t1: root.val += t1.val if t2: root.val += t2.val root.left = self.mergeTrees(t1.left if t1 else None, t2.left if t2 else None) root.right = self.mergeTrees(t1.right if t1 else None, t2.right if t2 else None) return root
def deleteNode(self, root: TreeNode, key: int) -> TreeNode: if not root: return root if root.val == key: if not root.left: return root.right elif not root.right: return root.left else: # Find successor succ = root.right while succ and succ.left: succ = succ.left root.val = succ.val root.right = self.deleteNode(root.right, succ.val) elif key < root.val: root.left = self.deleteNode(root.left, key) else: root.right = self.deleteNode(root.right, key) return root
def expan(node: TreeNode): if node.left is None and node.right is None: return node if node.left is None: return expan(node.right) if node.right is None: ltail = expan(node.left) node.right = node.left node.left = None return ltail ltail = expan(node.left) l = node.left r = node.right node.left = None node.right = l ltail.right = r rtail = expan(r) return rtail
def traverse(post_beg, post_end, in_beg, in_end): if post_end <= post_beg: return None # Find the index of current root in inorder traversal list idx = inorder_indices[postorder[post_end - 1]] root = TreeNode(inorder[idx]) # The portion of left subtree in the inorder list is given by [in_beg : idx] # The portion of right subtree in the inorder list is given by [idx + 1 : in_end] # The lengths of left and right are given by (idx - in_beg) and (in_end - idx) # Now we can obtain the portions of left and right subtree from the post order list: # Left subtree in the postorder list: [post_beg : idx] # Right subtree in the postorder list: [idx + 1 : in_end] # Construct both subtrees recursively root.left = traverse(post_beg, post_beg + idx - in_beg, in_beg, idx) root.right = traverse(post_end - in_end + idx, post_end - 1, idx + 1, in_end) return root
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: if not root1 and not root2: return None new_tree = TreeNode(0) n1 = root1 if root1 else TreeNode(0) n2 = root2 if root2 else TreeNode(0) new_tree.val = n1.val + n2.val new_tree.left = self.mergeTrees(n1.left, n2.left) new_tree.right = self.mergeTrees(n1.right, n2.right) return new_tree
def increasingBST(self, root: TreeNode) -> TreeNode: rtn = cur = TreeNode() def inorder(node): nonlocal cur if node: inorder(node.left) cur.right = TreeNode(node.val) cur = cur.right inorder(node.right) inorder(root) return rtn.right
def allPossibleFBT(self, n: int) -> List[TreeNode]: mem = { 1: [TreeNode()] } def helper(k): if k not in mem: rtn = [] for i in range(1, k - 1, 2): for left in helper(i): for right in helper(k - i - 1): cur = TreeNode() cur.left = left cur.right = right rtn.append(cur) mem[k] = rtn return mem[k] return helper(n)
def val2node(n: str): if n != 'None': return TreeNode(int(n)) else: return None
# -*- coding: utf-8 -*- # https://leetcode.com/problems/convert-bst-to-greater-tree/description/ from util import TreeNode class Solution(object): def convertBST(self, root): """ :type root: TreeNode :rtype: TreeNode """ return self.rec(root, 0)[1] def rec(self, root, sum): if root is None: return (sum, None) total, r = self.rec(root.right, sum) new_root = TreeNode(root.val + total) new_total, l = self.rec(root.left, new_root.val) new_root.left = l new_root.right = r return (new_total, new_root) solution = Solution() assert solution.convertBST(TreeNode.of([5, 2, 13])) == [18, 20, 13] assert solution.convertBST(TreeNode.of([2, 0, 3, -4, 1])) == [5, 6, 3, 2, 6]
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://leetcode.com/problems/diameter-of-binary-tree/description/ class Solution(object): def diameterOfBinaryTree(self, root): """ :type root: TreeNode :rtype: int """ if root is None: return 0 return self.inner(root)[0]-1 def inner(self, root): """return (max_diameter, max_depth)""" if root is None: return (0, 0) l_diameter, l_depth = self.inner(root.left) r_diameter, r_depth = self.inner(root.right) return (max(l_diameter, r_diameter, l_depth+r_depth+1) , max(l_depth, r_depth)+1) from util import TreeNode solution = Solution() assert solution.diameterOfBinaryTree(TreeNode.of([1,2,3,4,5])) == 3
""" if s is None and t is None: return True elif s is None or t is None: return False return self.equals(s, t) or self.isSubtree( s.left, t) or self.isSubtree(s.right, t) def equals(self, s, t): if s is None and t is None: return True elif s is None or t is None: return False return s.val == t.val and self.equals(s.left, t.left) and self.equals( s.right, t.right) from util import TreeNode solution = Solution() assert solution.isSubtree(TreeNode.of([3, 4, 5, 1, 2]), TreeNode.of([4, 1, 2])) assert not solution.isSubtree(TreeNode.of([3, 4, 5, 1, 2, None, None, 0]), TreeNode.of([4, 1, 2])) assert solution.isSubtree( TreeNode.of([ 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, 2 ]), TreeNode.of([1, None, 1, None, 1, None, 1, None, 1, None, 1, 2]))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://leetcode.com/problems/merge-two-binary-trees/description/ from util import TreeNode class Solution(object): def mergeTrees(self, t1, t2): """ :type t1: TreeNode :type t2: TreeNode :rtype: TreeNode """ if t1 is None and t2 is None: return None root = TreeNode(0) if t1: root.val += t1.val if t2: root.val += t2.val root.left = self.mergeTrees(t1.left if t1 else None, t2.left if t2 else None) root.right = self.mergeTrees(t1.right if t1 else None, t2.right if t2 else None) return root solution = Solution() assert solution.mergeTrees(TreeNode.of([1,3,2,5]), TreeNode.of([2,1,3,None,4,None,7])) == [3,4,5,5,4,None,7]
@lru_cache(None) def isLeaf(node: TreeNode): if node is None: return False return node.left is None and node.right is None def dfs(node: TreeNode): nonlocal ans if node is None: return if isLeaf(node.left): ans += node.left.val dfs(node.right) return dfs(node.left) dfs(node.right) dfs(root) return ans # @lc code=end t = TreeNode(2) tt = TreeNode(1) tt.left = t s = Solution() r = s.sumOfLeftLeaves(tt) print(r)
# condition to optimize from util import TreeNode class Solution(object): def pathSum(self, root, sum): return self.inner(root, sum, 0, {0: 1}) def inner(self, root, target, sofar, counts): if not root: return 0 ret = 0 complement = sofar + root.val - target if complement in counts: ret += counts[complement] sofar += root.val counts.setdefault(sofar, 0) # consider root.val is 0, what happens? counts[sofar] += 1 ret += self.inner(root.left, target, sofar, counts) ret += self.inner(root.right, target, sofar, counts) counts[sofar] -= 1 return ret solution = Solution() assert solution.pathSum( TreeNode.of([10, 5, -3, 3, 2, None, 11, 3, -2, None, 1]), 8) == 3