def generate_trees_2(self, n: int) -> List[TreeNode]: """ dp :param n: :return: """ def modify_tree(node: TreeNode, offset: int): if offset == 0 or not node: return node.val += offset modify_tree(node.left, offset) modify_tree(node.right, offset) # dp[i] stores the trees of n=i if n == 0: return [] dp = [[] for _ in range(n + 2)] dp[0].append(None) dp[1].append(TreeNode(1)) for i in range(2, n + 1): for j in range(1, i + 1): for left_tree in dp[j - 1]: for right_tree in dp[i - j]: root = TreeNode(j) root.left = left_tree new_right_tree = copy.deepcopy(right_tree) modify_tree(new_right_tree, j) root.right = new_right_tree dp[i].append(root) return dp[n]
def invert_tree(self, root: TreeNode) -> TreeNode: if not root: return None ans = TreeNode(root.val) ans.left = self.invert_tree(root.right) ans.right = self.invert_tree(root.left) return ans
def backtrack(start: int, end: int) -> TreeNode: """ Recursively generate TreeNode by sub list of preorder. :param start: the start index of sub list. :param end: the end index of sub list. :return: the generated TreeNode. """ val = preorder[start] root = TreeNode(val) if start == end: return root i = start + 1 split = -1 has_split = False # find the split num of the sub list if it exists. while i <= end: if preorder[i] > val: has_split = True split = i break i += 1 if has_split: if start + 1 <= split - 1: # process the left children TreeNode root.left = backtrack(start + 1, split - 1) if split <= end: # process the right children TreeNode root.right = backtrack(split, end) else: if start + 1 <= end: # process the left children TreeNode root.left = backtrack(start + 1, end) return root
def recover_from_preorder(self, s: str) -> TreeNode: if not s: return None i = 0 while i < len(s) and s[i] != '-': i += 1 root = TreeNode(s[:i]) store = [root] cur_depth, pre_depth = 0, -1 while i < len(s): if s[i] == '-': cur_depth += 1 i += 1 else: j = i + 1 while j < len(s) and s[j] != '-': j += 1 val = s[i:j] i = j cur_node = TreeNode(val) if cur_depth > pre_depth: # cur node is the left sub node for the previous node store[-1].left = cur_node else: # cur node is the right sibling for the previous node while cur_depth <= pre_depth: store.pop() pre_depth -= 1 store[-1].right = cur_node store.append(cur_node) pre_depth = cur_depth cur_depth = 0 return root
def backtrack(start: int, end: int) -> TreeNode: """ Recursively generate TreeNode by sub list of preorder. :param start: the start index of sub list. :param end: the end index of sub list. :return: the generated TreeNode. """ val = preorder[start] root = TreeNode(val) if start == end: return root i = start + 1 split = -1 has_split = False # find the split num of the sub list if it exists. while i <= end: if preorder[i] > val: has_split = True split = i break i += 1 if has_split: if start + 1 <= split - 1: # process the left children TreeNode root.left = backtrack(start + 1, split - 1) if split <= end: # process the right children TreeNode root.right = backtrack(split, end) else: if start + 1 <= end: # process the left children TreeNode root.left = backtrack(start + 1, end) return root
def insertIntoMaxTree(self, root: TreeNode, val: int) -> TreeNode: if root and val < root.val: root.right = self.insertIntoMaxTree(root.right, val) return root newRoot = TreeNode(val) newRoot.left = root return newRoot
def test(self): solution = Solution() treeNode1 = TreeNode(1) treeNode1.right = TreeNode(3) treeNode1.right.left = TreeNode(2) self.assertEqual(solution.getMinimumDifference(treeNode1), 1)
def addOneRow(self, root, v, d): """ :type root: TreeNode :type v: int :type d: int :rtype: TreeNode """ if d == 1: treeNode = TreeNode(v) treeNode.left = root return treeNode elif d == 2: left = root.left right = root.right root.left = TreeNode(v) root.right = TreeNode(v) root.left.left = left root.right.right = right return root else: if root.left: self.addOneRow(root.left, v, d - 1) if root.right: self.addOneRow(root.right, v, d - 1) return root
def list2tree(l: List[int]) -> Optional[TreeNode]: if not l: return None root = TreeNode(int(l[0])) node_queue = [root] front = 0 index = 1 while index < len(l): node = node_queue[front] front = front + 1 item = l[index] index = index + 1 if item is not None: left_number = int(item) node.left = TreeNode(left_number) node_queue.append(node.left) if index >= len(l): break item = l[index] index = index + 1 if item is not None: right_number = int(item) node.right = TreeNode(right_number) node_queue.append(node.right) return root
def recover(node: TreeNode) -> None: if node: if node.val == swap_nums[0]: node.val = swap_nums[1] elif node.val == swap_nums[1]: node.val = swap_nums[0] recover(node.left) recover(node.right)
def recur(start: int, end: int) -> TreeNode: if start > end: return None mid = start + (end - start) // 2 root = TreeNode(nums[mid]) root.left = recur(start, mid - 1) root.right = recur(mid + 1, end) return root
def remove(node: TreeNode) -> Optional[TreeNode]: if not node.left: return node.right if not node.right: return node.left node.val = find_min(node.right) node.right = self.delete_node(node.right, node.val) return node
def recur(node1: TreeNode, node2: TreeNode) -> TreeNode: if not node1: return node2 if not node2: return node1 result = TreeNode(node1.val + node2.val) result.left = recur(node1.left, node2.left) result.right = recur(node1.right, node2.right) return result
def recur(start: int, end: int) -> TreeNode: # [start, end) if end == start: return None mid = (start + end) // 2 root = TreeNode(nums[mid]) root.left = recur(start, mid) root.right = recur(mid + 1, end) return root
def test(self): solution = Solution() tree1 = TreeNode(1) tree1.left = TreeNode(0) tree1.right = TreeNode(2) tree1output = TreeNode(1) tree1output.right = TreeNode(2) self.assertEqual( assertTreeNodeEqual(solution.trimBST(tree1, 1, 2), tree1output), True)
def construct_maximum_binary_tree(self, nums: List[int]) -> TreeNode: if not nums: return None max_num = max(nums) max_index = nums.index(max_num) root = TreeNode(max(nums)) root.left = self.construct_maximum_binary_tree(nums[:max_index]) root.right = self.construct_maximum_binary_tree(nums[max_index + 1:]) return root
def construct_maximum_binary_tree(self, nums: List[int]) -> TreeNode: if not nums: return None max_num = max(nums) max_index = nums.index(max_num) root = TreeNode(max(nums)) root.left = self.construct_maximum_binary_tree(nums[:max_index]) root.right = self.construct_maximum_binary_tree(nums[max_index + 1:]) return root
def dfs(node: Optional[TreeNode]): if node.val < val: if not node.right: node.right = TreeNode(val) else: dfs(node.right) if node.val > val: if not node.left: node.left = TreeNode(val) else: dfs(node.left)
def build_tree(self, inorder: List[int], postorder: List[int]) -> TreeNode: root = TreeNode(postorder[-1]) pos = inorder.index(root.val) l_inorder = inorder[:pos] r_inorder = inorder[pos + 1:] if l_inorder: root.left = self.build_tree(l_inorder, postorder[:len(l_inorder)]) if r_inorder: root.right = self.build_tree( r_inorder, postorder[len(postorder) - len(r_inorder) - 1:-1]) return root
def build_tree(self, preorder: List[int], inorder: List[int]) -> TreeNode: if not preorder: return None root = TreeNode(preorder[0]) index = inorder.index(preorder[0]) left_tree_inorder = inorder[:index] right_tree_inorder = inorder[index + 1:] left_tree_preorder = preorder[1:index + 1] right_tree_preorder = preorder[index + 1:] root.left = self.build_tree(left_tree_preorder, left_tree_inorder) root.right = self.build_tree(right_tree_preorder, right_tree_inorder) return root
def upside_down_binary_tree(self, root: TreeNode) -> TreeNode: new_root = None parent_right_child = None # left child -> root, root -> right child, right child -> left child while root: left_child = root.left root.left = parent_right_child parent_right_child = root.right root.right = new_root new_root = root root = left_child return new_root
def increasing_bst2(self, root: TreeNode) -> TreeNode: dummy = cur = TreeNode(-1) stack = [] while root or stack: if root: stack.append(root) root = root.left else: root = stack.pop() cur.right = TreeNode(root.val) cur = cur.right root = root.right return dummy.right
def backtrack(left: int, right: int) -> List[TreeNode]: if left > right: return [None] if left == right: return [TreeNode(left)] trees = [] for i in range(left, right + 1): for left_tree in backtrack(left, i - 1): for right_tree in backtrack(i + 1, right): root = TreeNode(i) root.left = left_tree root.right = right_tree trees.append(root) return trees
def increasing_bst3(self, root: TreeNode) -> TreeNode: dummy = cur = TreeNode(-1) stack = list() while root or stack: if root: stack.append(root) root = root.left else: root = stack.pop() root.left = None cur.right = root cur = cur.right root = root.right return dummy.right
def test(self): solution = Solution() treeNode1 = TreeNode(4) treeNode1.left = TreeNode(2) treeNode1.right = TreeNode(6) treeNode1.left.left = TreeNode(1) treeNode1.left.right = TreeNode(3) self.assertEqual(solution.minDiffInBST(treeNode1), 1)
def test(self): solution = Solution() treeNode1 = TreeNode(3) treeNode1.left = TreeNode(9) treeNode1.right = TreeNode(20) treeNode1.right.left = TreeNode(15) treeNode1.right.right = TreeNode(7) self.assertEqual(solution.averageOfLevels(treeNode1), [3, 14.5, 11])
def test(self): solution = Solution() rootTreeNode1 = TreeNode(6) rootTreeNode1.left = TreeNode(3) rootTreeNode1.left.right = TreeNode(2) rootTreeNode1.left.right.right = TreeNode(1) rootTreeNode1.right = TreeNode(5) rootTreeNode1.right.left = TreeNode(0) self.assertTrue( assertTreeNodeEqual( solution.constructMaximumBinaryTree([3, 2, 1, 6, 0, 5]), rootTreeNode1))
def insertIntoBST(self, root, val): """ :type root: TreeNode :type val: int :rtype: TreeNode """ if root == None: root = TreeNode(val) return root if root.val > val: root.left = self.insertIntoBST(root.left, val) return root if root.val < val: root.right = self.insertIntoBST(root.right, val) return root return root
def generate_trees_1(self, n: int) -> List[TreeNode]: """ recursive :param n: :return: """ if n == 0: return [] if n == 1: return [TreeNode(1)] def backtrack(left: int, right: int) -> List[TreeNode]: if left > right: return [None] if left == right: return [TreeNode(left)] trees = [] for i in range(left, right + 1): for left_tree in backtrack(left, i - 1): for right_tree in backtrack(i + 1, right): root = TreeNode(i) root.left = left_tree root.right = right_tree trees.append(root) return trees return backtrack(1, n)
def dfs(node: TreeNode) -> None: if node.right: dfs(node.right) self.v += node.val node.val = self.v if node.left: dfs(node.left)
def bstFromPreorder(self, preorder: List[int]) -> TreeNode: if len(preorder) == 0: return None if len(preorder) == 1: return TreeNode(preorder[0]) ans = TreeNode(preorder[0]) idx = 1 for i in range(1, len(preorder)): idx = i if preorder[i] > preorder[0]: break if preorder[idx] < preorder[0]: idx += 1 ans.left = self.bstFromPreorder(preorder[1:idx]) ans.right = self.bstFromPreorder(preorder[idx:]) return ans
def add_node(value, depth, store): store[depth] = TreeNode(value) if depth == 0: return if not store[depth - 1].left: store[depth - 1].left = store[depth] else: store[depth - 1].right = store[depth]