def sortedListToBST(self, head: ListNode) -> TreeNode: # 空列表 return if head is None: return None # 单节点 return if head.next is None: return TreeNode(head.val) # 2个节点 return if head.next and head.next.next is None: root = TreeNode(head.next.val) root.left = TreeNode(head.val) return root # 快慢指针,快指针到终点时,慢指针正好是中点 prev = fast = slow = head while True: if fast.next: fast = fast.next else: break if fast.next: fast = fast.next else: break if slow.next: prev = slow slow = slow.next # 断开链接到中点的link prev.next = None root = TreeNode(slow.val) # 递归生成子树 root.left = self.sortedListToBST(head) root.right = self.sortedListToBST(slow.next) return root
def test_findTilt(): t1 = TreeNode(1) t2 = TreeNode(2) t3 = TreeNode(3) t1.left = t2 t1.right = t3 assert findTilt(t1) == 1, findTilt(t1) t4 = TreeNode(4) t5 = TreeNode(5) t2.left = t4 t3.left = t5 assert findTilt(t1) == 11, findTilt(t1)
def deserialize(self, data): """Decodes your encoded data to tree. :type data: str :rtype: TreeNode """ if not data: return None try: left_bound = data.index('(') except ValueError: return TreeNode(int(data)) right_bound = 0 counter = 0 while right_bound < len(data): if data[right_bound] == '(': counter += 1 elif data[right_bound] == ')': counter -= 1 if counter == 0: right_bound += 1 break right_bound += 1 val = int(data[:left_bound]) left_data = data[left_bound+1:right_bound-1] right_data = data[right_bound+1:-1] node = TreeNode(val) node.left = self.deserialize(left_data) node.right = self.deserialize(right_data) return node
def node_from_preorder(p_i: int, p_j: int) -> TreeNode: """ p_i and p_j is left and right bounds for preorder list If bounds not valid (list not empty) -> return null Create node from left element in preorder With binary search search for first element which index in inorder is greater than node's Link node created with bounds p_i + 1 (miss first element) and left as left child Link node created with bound left and p_j as right child Return node """ if p_i >= p_j: return None node = TreeNode(preorder[p_i]) left, right = p_i + 1, p_j - 1 while left <= right: mid = (left + right) // 2 if indices[preorder[mid]][1] > indices[node.val][1]: right = mid - 1 else: left = mid + 1 node.left = node_from_preorder(p_i + 1, left) node.right = node_from_preorder(left, p_j) return node
def build(stop): if inorder and inorder[-1] != stop: root = TreeNode(preorder.pop()) root.left = build(root.val) inorder.pop() root.right = build(stop) return root
def buildTree(preorder: 'list[int]', inorder: 'list[int]') -> TreeNode: if inorder: ind = inorder.index(preorder.pop(0)) root = TreeNode(inorder[ind]) root.left = buildTree(preorder, inorder[0:ind]) root.right = buildTree(preorder, inorder[ind + 1:]) return root
def deleteNode(self, root: TreeNode, key: int) -> TreeNode: """ 如果 node.val == key,分三种情况 1. 如果 node 是叶子节点, 直接令 node = None 2. 如果 node 只有一个子节点,则把子节点移动到当前节点替换 3. 如果 node 有两个子节点,则用 right 的最小节点替换当前节点 """ if not root: return None if key < root.val: # 递归左侧 root.left = self.deleteNode(root.left, key) elif key > root.val: # 递归右侧 root.right = self.deleteNode(root.right, key) else: # 当 node.val == key # 本身就包含了 root.left == root.right == None 的情况 if root.left is None: return root.right elif root.right is None: return root.left else: min_node = self.findMin(root.right) root.val = min_node.val root.right = self.deleteNode(root.right, min_node.val) return root
def helper(s): cur = next(s) if cur == "#": return node = TreeNode(cur) node.left = helper(s) node.right = helper(s) return node
def sortedListToBST(self, head: ListNode) -> TreeNode: """ :param nums: 从小到大排好序了 """ if not head: return None if not head.next: return TreeNode(head.val) slow = head fast = head.next.next while fast and fast.next: slow = slow.next fast = fast.next.next mid = slow # 从 mid 开始截断,这样后面再传 head 就相当于只传前半段 tmp = mid.next mid.next = None root = TreeNode(tmp.val) root.left = self.sortedListToBST(head) root.right = self.sortedListToBST(tmp.next) return root
def invertTree(self, root: TreeNode) -> TreeNode: """ 递归 Time O(n) Space O(n) """ if root is None: return root if root.left is None and root.right is None: return root root.left, root.right = root.right, root.left root.left = self.invertTree(root.left) root.right = self.invertTree(root.right) return root
def sortedArrayToBST(self, nums: List[int]): if not nums: return mid = len(nums) // 2 root = TreeNode(nums[mid]) root.left = self.sortedArrayToBST(nums[:mid]) root.right = self.sortedArrayToBST(nums[mid + 1:]) return root
def addToTree(arr, start, end): if end < start: return None mid = (start + end) // 2 n = TreeNode(arr[mid]) n.left = addToTree(arr, start, mid - 1) n.right = addToTree(arr, mid + 1, end) return n
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: if len(preorder) == 0: return None mid = inorder.index(preorder[0]) t = TreeNode(preorder[0]) t.left = self.buildTree(preorder[1:mid + 1], inorder[:mid]) t.right = self.buildTree(preorder[mid + 1:], inorder[mid + 1:]) return t
def generate(self, l, r): if l > r: return None mid = (l + r) / 2 node = TreeNode(self.nums[mid]) node.left = self.generate(l, mid - 1) node.right = self.generate(mid + 1, r) return node
def sortedArrayToBST(self, nums: List[int]) -> TreeNode: if len(nums) == 0: return None i = (len(nums) - 1) // 2 root = TreeNode(nums[i]) root.left = self.sortedArrayToBST(nums[:i]) root.right = self.sortedArrayToBST(nums[i + 1:]) return root
def help(nums, l, h): m = (l + h) // 2 node = TreeNode(nums[m]) if l <= m - 1: node.left = help(nums, l, m - 1) if m + 1 <= h: node.right = help(nums, m + 1, h) return node
def sorted_array2bst(nums): if not nums: return None mid = len(nums) // 2 root = TreeNode(nums[mid]) root.left = sorted_array2bst(nums[:mid]) root.right = sorted_array2bst(nums[mid+1:]) return root
def min_height_bst_from_sorted_array(A): if not A: return None mid = len(A) / 2 root = TreeNode(A[mid]) root.left = min_height_bst_from_sorted_array(A[:mid]) root.right = min_height_bst_from_sorted_array(A[mid + 1:]) return root
def deserialize_tree_util(nodes): val = nodes.pop() if val == '$': return None root = TreeNode(int(val)) root.left = deserialize_tree_util(nodes) root.right = deserialize_tree_util(nodes) return root
def sortedArrayToBST_1(self, nums, l, h): if h < l: return None mid = (l+h) / 2 node = TreeNode(nums[mid]) node.left = self.sortedArrayToBST_1(nums, l, mid-1) node.right = self.sortedArrayToBST_1(nums, mid+1, h) return node
def reConstructBinaryTree(self, pre, tin): # assert(len(pre) == len(tin)) if len(pre) == 0: return None treeNode = TreeNode(pre[0]) mid = tin.index(pre[0]) treeNode.left = self.reConstructBinaryTree(pre[1:mid + 1], tin[0:mid]) treeNode.right = self.reConstructBinaryTree(pre[mid + 1:len(pre)], tin[mid + 1:len(tin)]) return treeNode
def des(): if not data: return None val = data.pop(0) if val == '#': return None node = TreeNode(val) node.left = des() node.right = des() return node
def buildTree(self, preorder: List[int], inorder: List[int]): if not preorder or not inorder: return root_val = preorder.pop(0) root = TreeNode(root_val) idx = inorder.index(root_val) root.left = self.buildTree(preorder, inorder[:idx]) root.right = self.buildTree(preorder, inorder[idx + 1:]) return root
def buildTree(postorder, inorder): if not postorder or not inorder: return None tree_val = postorder[-1] root = TreeNode(tree_val) left_index = inorder.index(tree_val) root.left = buildTree(postorder[:left_index], inorder[:left_index]) root.right = buildTree(postorder[left_index:-1], inorder[left_index + 1:]) return root
def dfs(node: TreeNode) -> TreeNode: if node is None: return dfs(node.left) dfs(node.right) node.left, node.right = node.right, node.left return node
def create_binary_search_tree(array, start, end): if end < start: return None middle = (start + end) // 2 root = TreeNode(array[middle]) root.left = create_binary_search_tree(array, start, middle - 1) root.right = create_binary_search_tree(array, middle + 1, end) return root
def deserialize(nodes): if len(nodes) < 1: return None if nodes[-1] == "$": nodes.pop() return None root = TreeNode(int(nodes.pop())) root.left = deserialize(nodes) root.right = deserialize(nodes) return root
def helper(): val = vals.pop() if val == '': return None node = TreeNode(int(val)) node.left = helper() node.right = helper() return node
def dfs(first: TreeNode, second: TreeNode) -> TreeNode: """ If both node not null -> update first node values with second node If only first not null -> stay first If only second not null -> init first with values of second Otherwise -> return null Return (updated) first """ if first: if second: first.val += second.left first.left = dfs(first.left, second.left) first.right = dfs(first.right, second.right) else: if second: first = TreeNode(second.val) first.left = dfs(None, second.left) first.right = dfs(None, second.right) return first
def pruneTree(self, root: TreeNode) -> TreeNode: if not root: return None root.left = self.pruneTree(root.left) root.right = self.pruneTree(root.right) if root.val == 0 and not root.right and not root.left: return None return root
def flatten(self, root: TreeNode) -> None: if not root: return if root.right and root.left: traverse_to_next(root.left).right = root.right if root.left: root.right = root.left root.left = None if root.right: self.flatten(root.right)
def go(node: TreeNode) -> TreeNode: if node is None: return None if node.val < L: return go(node.right) elif node.val > R: return go(node.left) else: node.left = go(node.left) node.right = go(node.right) return node
def trim(node: TreeNode) -> TreeNode: if not node: return None elif node.val > R: # 右子树的值都大于 node.val,当 node.val 都大于 R,则直接抛弃右子树 return trim(node.left) elif node.val < L: return trim(node.right) else: node.left = trim(node.left) node.right = trim(node.right) return node
def test(): root = TreeNode(1) root.left = TreeNode(2) root.right = TreeNode(3) root.left.left = TreeNode(4) root.left.right = TreeNode(5) root.right.left = TreeNode(6) root.right.right = TreeNode(7) print("LCA(4, 5) = ", LCA(root, 4, 5).val) print("LCA(4, 6) = ", LCA(root, 4, 6).val) print("LCA(3, 4) = ", LCA(root, 3, 4).val) print("LCA(2, 4) = ", LCA(root, 2, 4).val)
def create_tree_by_preorder(pre_list, mid_list): if not pre_list: return None if not mid_list: return None tree_val = pre_list[0] root = TreeNode(tree_val) left_index = mid_list.index(tree_val) root.left = create_tree_by_preorder(pre_list[1:left_index + 1], mid_list[:left_index]) root.right = create_tree_by_preorder(pre_list[left_index + 1:], mid_list[left_index + 1:]) return root
def op(start, end): if start == end: return TreeNode(nums[start]) elif end - start == 1: root = TreeNode(nums[start]) root.right = TreeNode(nums[end]) return root else: pivot = (start + end)/2 root = TreeNode(nums[pivot]) root.left = op(start, pivot-1) root.right = op(pivot+1, end) return root
def generate(self, l, r): if l > r: return [None] res = [] for i in range(l, r + 1): for left in self.generate(l, i - 1): for right in self.generate(i + 1, r): node = TreeNode(i) node.left = left node.right = right res.append(node) return res
def magic(pre, post): if not pre: return None elif len(pre) == 1: return TreeNode(pre[0]) else: pv = pre[0] ll = post.index(pre[1]) + 1 l = magic(pre[1 : 1 + ll], post[:ll]) r = magic(pre[ll + 1 :], post[ll:-1]) p = TreeNode(pv) p.left = l p.right = r return p
def constructBT(s): if not s: return None # print(f"s: {s}") paren = s.find("(") val = int(s) if paren == -1 else int(s[:paren]) node = TreeNode(val) if paren == -1: return node # if no parentheses found, then return start, count = paren, 0 for i in range(start, len(s)): if s[i] == "(": count += 1 elif s[i] == ")": count -= 1 if count == 0 and start == paren: # build the left child node.left = constructBT(s[start+1:i]) start = i+1 # start process the right child's string elif count == 0: # build the right child node.right = constructBT(s[start+1:i]) return node
def sortedListToBST(self, head): """ :type head: ListNode :rtype: TreeNode """ if head is None: return None fast, prev, slow = head, None, head while fast and fast.next: fast = fast.next.next prev, slow = slow, slow.next root = TreeNode(slow.val) if prev: prev.next = None else: return root root.left = self.sortedListToBST(head) root.right = self.sortedListToBST(slow.next) return root
while node or st: if node: st.append(node) if not node.left and not node.right: nodes.append(node) node = node.left else: node = st.pop() node = node.right # get the right boundary rights = [] while right and (right.left or right.right): rights.append(right) if right.right: right = right.right else: right = right.left nodes.extend(rights[::-1]) return nodes # testing from utils import TreeNode n1 = TreeNode(1) n2 = TreeNode(2) n3 = TreeNode(3) n4 = TreeNode(4) n1.right = n2 n2.left = n3 n2.right = n4 nodes = boundaryOfBinaryTree_2(n1) print(f"{[n.val for n in nodes]}")
if not root: return if interval.left <= root.val <= interval.right: helper(root.left) res.append(root.val) helper(root.right) elif interval.left > root.val: helper(root.right) else: helper(root.left) res = [] helper(root) return res root = TreeNode(19) root.left = TreeNode(7) root.left.left = TreeNode(3) root.left.left.left = TreeNode(2) root.left.left.right = TreeNode(5) root.left.right = TreeNode(11) root.left.right.right = TreeNode(17) root.left.right.right.left = TreeNode(13) root.right = TreeNode(43) root.right.left = TreeNode(23) root.right.left.right = TreeNode(37) root.right.left.right.left = TreeNode(29) root.right.left.right.left.right = TreeNode(31) root.right.left.right.right = TreeNode(41)
from bisect import bisect_left, bisect_right previous = [] res = maxsize def minDiffBT(root): if not root: return minDiffBT(root.left) global res, previous if previous: floor = bisect_left(previous, root.val) # find the insert position print(f"val: {root.val}, floor: {floor}, previous: {previous}") if floor != len(previous): # if the insert position is within the index range res = min(res, abs(root.val - previous[floor])) else: # if the insert position pass the index range res = min(res, abs(root.val - previous[floor-1])) if floor + 1 < len(previous): # also check the potential bigger elements res = min(res, abs(previous[floor+1] - root.val)) previous = previous[:floor] + [root.val] + previous[floor:] # insert the current element else: previous.append(root.val) print(f"min res: {res}") minDiffBT(root.right) # testing t1 = TreeNode(1) t2 = TreeNode(3) t3 = TreeNode(6) t2.left = t3 t2.right = t1 minDiffBT(t2) print(f"min diff in BT: {res}")
if not node: return None, None left_min, left_max = dfs(node.left) right_min, right_max = dfs(node.right) node.left = None node.right = left_min or right_min if left_max: left_max.right = right_min return node, right_max or left_max or node dfs(root) if __name__ == "__main__": from utils import TreeNode n1 = TreeNode(1) n2 = TreeNode(2) n3 = TreeNode(3) n1.left = n2 n1.right = n3 Solution().flatten(n1) assert n1.right is n2 assert n1.left is None assert n2.left is None assert n2.right is n3 assert n3.left is None and n3.right is None
""" 538 convert bst to greater tree """ from utils import TreeNode sum = 0 def convertBST(root): # traverse from right node -> current node -> left node if not root: return convertBST(root.right) global sum sum += root.val print(f"{root.val} -> {sum}") root.val = sum convertBST(root.left) t1 = TreeNode(5) t2 = TreeNode(2) t3 = TreeNode(13) t4 = TreeNode(10) t1.left = t2 t1.right = t3 t3.left = t4 convertBST(t1)
def test_chapter4_8(root, left, right, parent): tree = TreeNode(root, TreeNode(left), TreeNode(right)) root = TreeNode(parent) root.left = tree assert chapter4.prob4_8(root, tree) is True
if T2 is a sub-tree of T1. """ def is_subtree(T1, T2): # Empty tree is *always* subset of another tree if T2 is None: return True # We've gone through both trees and ended at same time, means it's same if T1 is None and T2 is None: return True # If either one finishes first, then it's not the same if T1 is None or T2 is None: return False return is_subtree(T1.left, T2.left) and is_subtree(T1.right, T2.right) subtree = find_node(T1, T2.data) # We couldn't find the node if not subtree: return False return is_subtree(subtree, T2) if __name__ == '__main__': tree = TreeNode(5, TreeNode(1), TreeNode(10)) root = TreeNode(100) root.left = tree another = TreeNode(5, TreeNode(1), TreeNode(10)) print(find_node(root, 5))