def rec(t1, t2): if not t1 and not t2: return None if not t1: ### or can just deep clone t2 #t = copy.deepcopy(t2) t = TreeNode(t2.val) t.left = rec(None, t2.left) t.right = rec(None, t2.right) elif not t2: ### or can just deep clone t1 #t = copy.deepcopy(t1) t = TreeNode(t1.val) t.left = rec(t1.left, None) t.right = rec(t1.right, None) else: t = TreeNode(t1.val + t2.val) t.left = rec(t1.left, t2.left) t.right = rec(t1.right, t2.right) return t
def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: if not t1: return t2 root = t1 stack = [(t1, t2)] while stack: t1, t2 = stack.pop() if not t1 or not t2: continue t1.val += t2.val if not t1.left: t1.left = t2.left elif t2.left: # both t1 and t2 have left nodes stack.append((t1.left, t2.left)) if not t1.right: t1.right = t2.right elif t2.right: # both t1 and t2 have right nodes stack.append((t1.right, t2.right)) return root
def dfs(start, end): if start >= end: return None # Find first '(' i = s.find('(', start, end) if i < 0: return TreeNode(int(s[start:end])) # Find index j of char ')' that ends left subtree net = 0 for j in range(i, end): if s[j] in d: net += d[s[j]] if net == 0: break root = TreeNode(int(s[start:i])) root.left = dfs(i + 1, j) # exclude parentheses at this level root.right = dfs(j + 2, end - 1) # exclude parentheses at this level return root
def str2tree(self, s: str) -> TreeNode: if not s: return None # Find first '(' i = s.find('(') if i < 0: return TreeNode(int(s)) # Find index j of char ')' that ends left subtree net = 0 j = i while j < len(s): if s[j] == '(': net += 1 elif s[j] == ')': net -= 1 if net == 0: break j += 1 root = TreeNode(int(s[:i])) root.left = self.str2tree(s[i + 1:j]) # exclude parentheses at this level root.right = self.str2tree( s[j + 2:-1]) # exclude parentheses at this level return root
def test(self): t = TreeNode(3) t.left = TreeNode(9) t.right = TreeNode(20) t.right.left = TreeNode(15) t.right.right = TreeNode(7) self.assertEqual(3, Solution().maxDepth(t))
def dfs(i): # Check if subtree is empty. if s[i] in ['(', ')']: return None, i start = i # while i < n and (s[i] == '-' or s[i].isdigit()): while i < n and s[i] not in ['(', ')']: i += 1 # if start == i: # alternative to checking s[i] at start # return None, i node = TreeNode(int(s[start:i])) if i < n and s[i] == '(': # left subtree i += 1 # skip '(' node.left, i = dfs(i) i += 1 # skip ')' if i < n and s[i] == '(': # right subtree i += 1 # skip '(' node.right, i = dfs(i) i += 1 # skip ')' return node, i
def invertTree(self, root: TreeNode) -> TreeNode: if not root: return None right, left = root.right, root.left root.left = self.invertTree(right) root.right = self.invertTree(left) return root
def test(self): t = TreeNode(3) t.left = TreeNode(9) t.right = TreeNode(20) t.right.left = TreeNode(15) t.right.right = TreeNode(7) self.assertEqual(2, BFS().minDepth(t)) self.assertEqual(2, DFS().minDepth(t))
def test_not_bst(self): t = TreeNode(5) t.left = TreeNode(1) t.right = TreeNode(4) t.right.left = TreeNode(3) t.right.right = TreeNode(6) for x in self.solutions: self.assertFalse(x.isValidBST(t))
def test_true(self): t = TreeNode(3) t.left = TreeNode(9) t.right = TreeNode(20) t.right.left = TreeNode(15) t.right.left = TreeNode(7) self.assertTrue(BruteForceTopDownRecursion().isBalanced(t)) self.assertTrue(BottomUp().isBalanced(t))
def construct(qianxu, zhongxu): if not qianxu or not zhongxu: return root = TreeNode(qianxu[0]) pos = zhongxu.index(qianxu[0]) root.left = construct(qianxu[1:pos + 1], zhongxu[0:pos]) root.right = construct(qianxu[pos + 1:], zhongxu[pos + 1:]) return root
def build_mirror(root): if not root: return None t = TreeNode(root.val) t.left = build_mirror(root.right) t.right = build_mirror(root.left) return t
def _sortedArrayToBST(self, nums, low, high): if low > high: return None if low == high: return TreeNode(nums[low]) mid = low + (high - low) // 2 root = TreeNode(nums[mid]) root.left = self._sortedArrayToBST(nums, low, mid - 1) root.right = self._sortedArrayToBST(nums, mid + 1, high) return root
def insert_node(root: TreeNode, parent: TreeNode, data: int): if not root: return TreeNode(data, parent=parent) if data < root.data: root.left = insert_node(root.left, root, data) else: root.right = insert_node(root.right, root, data) return root
def test_false(self): t = TreeNode(1) t.left = TreeNode(2) t.right = TreeNode(2) t.left.left = TreeNode(3) t.left.right = TreeNode(3) t.left.left.left = TreeNode(4) t.left.left.right = TreeNode(4) self.assertFalse(BruteForceTopDownRecursion().isBalanced(t)) self.assertFalse(BottomUp().isBalanced(t))
def helper(self, start: int, end: int) -> TreeNode: if start > end: return None mid = (start + end) // 2 left_child: TreeNode = self.helper(start, mid - 1) parent = TreeNode(self.list.val) # 按顺序读取链表中的元素并插入树 parent.left = left_child self.list = self.list.next parent.right = self.helper(mid + 1, end) return parent
def dfs_bottom_up(p: TreeNode, parent: TreeNode) -> TreeNode: if p is None: return parent root = dfs_bottom_up(p.left, p) if parent is None: p.left = None else: p.left = parent.right p.right = parent return root
def build(low, high): if low > high: return None root = TreeNode(postorder.pop()) mid = inorder_dict[root.val] root.right = build(mid + 1, high) root.left = build(low, mid - 1) return root
def post_dfs(stop): if postorder and inorder[-1] != stop: root = TreeNode(postorder.pop()) root.right = post_dfs(root.val) inorder.pop() root.left = post_dfs(stop) return root
def buildTree(self, inorder, postorder): """ :type inorder: List[int] :type postorder: List[int] :rtype: TreeNode """ if (not inorder) or (not postorder): return None root, i = TreeNode(postorder[-1]), inorder.index(postorder[-1]) root.left = self.buildTree(inorder[:i], postorder[:i]) root.right = self.buildTree(inorder[i + 1:], postorder[i:-1]) return root
def buildTree(self, preorder, inorder): """ :type preorder: List[int] :type inorder: List[int] :rtype: TreeNode """ if (not preorder) or (not inorder): return None root, i = TreeNode(preorder[0]), inorder.index(preorder[0]) root.left = self.buildTree(preorder[1:i + 1], inorder[:i]) root.right = self.buildTree(preorder[i + 1:], inorder[i + 1:]) return root
def build_bt(inorder, postorder): if not inorder or not postorder: return None root = TreeNode(postorder.pop()) # modifies "postorder" r = inorder.index(root.val) # O(n) time root.right = build_bt(inorder[r + 1:], postorder) # O(n) time and extra space root.left = build_bt(inorder[:r], postorder) # O(n) time and extra space return root
def Deserialize(self, s): if s is None or len(s) == 0 or self.index >= len(s): return None num = s[self.index] if s[self.index] == '$' else int(s[self.index]) self.index += 2 if num != '$': root = TreeNode(num) root.left = self.Deserialize(s) root.right = self.Deserialize(s) return root return None
def dfs(l): if not l: return [] if len(l) == 1: return [TreeNode(l[0])] res = list() for i in l: left, right = dfs(range(l[0], i)), dfs(range(i + 1, l[-1] + 1)) for j in range(max(len(left), 1)): for k in range(max(len(right), 1)): root = TreeNode(i) if j < len(left): root.left = left[j] if k < len(right): root.right = right[k] res.append(root) return res
def sortedArrayToBST(self, nums): """ :type nums: List[int] :rtype: TreeNode """ l = len(nums) mid = int(l / 2) if l == 0: return None if l == 1: return TreeNode(nums[0]) root = TreeNode(nums[mid]) root.left = self.sortedArrayToBST(nums[:mid]) root.right = self.sortedArrayToBST(nums[mid + 1:]) return root
def sortedListToBST(self, head): """ :type head: ListNode :rtype: TreeNode """ if not head: return if not head.next: return TreeNode(head.val) fast = slow = preslow = head while fast and fast.next: fast, slow, preslow = fast.next.next, slow.next, slow root = TreeNode(slow.val) root.right, preslow.next = self.sortedListToBST(slow.next), None root.left = self.sortedListToBST(head) return root
def sortedArrayToBST(self, nums): """ Divide and Conquer Runtime: 64 ms, faster than 97.63% of Python3 Time O(n) Space O(logn) :type nums: List[int] :rtype: TreeNode """ if len(nums) == 0: return None root = TreeNode(nums[len(nums)//2]) root.left = self.sortedArrayToBST(nums[0:len(nums)//2]) root.right = self.sortedArrayToBST(nums[len(nums)//2+1: len(nums)]) return root
def constrcut(self, pre, tin, preStart, preEnd, inStart, inEnd): if preStart > preEnd or inStart > inEnd: return None rootIndex = 0 for i in range(inStart, inEnd + 1): if pre[preStart] == tin[i]: rootIndex = i break root = TreeNode(pre[preStart]) root.left = self.constrcut(pre, tin, preStart + 1, preStart + rootIndex - inStart, inStart, rootIndex - 1) root.right = self.constrcut(pre, tin, preStart + rootIndex - inStart + 1, preEnd, rootIndex + 1, inEnd) return root
def build(head, count): #if (not head) or (count == 0): if count == 0: return None mid = head mid_count = count // 2 # tree is left-biased #mid_count = (count - 1) // 2 # tree is right-biased for _ in range(mid_count): mid = mid.next root = TreeNode(mid.val) root.left = build(head, mid_count) root.right = build(mid.next, count - mid_count - 1) return root
def build(low, high): nonlocal head if low > high: return None mid = (low + high) // 2 # tree is right-biased #mid = (low + high + 1) // 2 # tree is left-biased left = build(low, mid - 1) root = TreeNode(head.val) root.left = left head = head.next root.right = build(mid + 1, high) return root