def build_tree(l: int, r: int) -> Optional[BstNode]: if r < l: return None m = (l + r) // 2 root: BstNode = BstNode(A[m]) root.left = build_tree(l, m - 1) root.right = build_tree(m + 1, r) return root
def build_min_height_bst_from_sorted_array(A: List[int]) -> Optional[BstNode]: if not A: return None return BstNode( A[len(A) // 2], left=build_min_height_bst_from_sorted_array(A[:len(A) // 2]), right=build_min_height_bst_from_sorted_array(A[len(A) // 2 + 1:]))
def reconstruct(lo, hi): if lo > hi: return None mid = (lo + hi) // 2 return BstNode(A[mid], reconstruct(lo, mid - 1), reconstruct(mid + 1, hi))
def reconstruct_tree(preorder, inorder): # TODO - you fill in here. # 1. root is first node in preorder traversal # 2. use root to divide inorder traversal into left and right subtrees (inorder) # 3. use (left,right) inorder traversal set to partition preorder traversal # after root element into (left,right) preorder traversal # print('preorder={},inorder={}'.format(preorder, inorder)) if not preorder: print("returning None") return None # 1. root_value = preorder[0] root = BstNode(root_value) # 2. root_index = inorder.index(root_value) # root_index = element_index[root_value] print('root_index=', root_index) # 3. inorder_left_tree = inorder[:root_index] inorder_right_tree = inorder[root_index + 1:] print('inorder_left_tree={},inorder_right_tree={}'.format( inorder_left_tree, inorder_right_tree)) preorder_left_tree = preorder[1:root_index + 1] preorder_right_tree = preorder[root_index + 1:] print('preorder_left_tree={},preorder_right_tree={}'.format( preorder_left_tree, preorder_right_tree)) # root.left = reconstruct_tree(preorder_left_tree, inorder_left_tree) root.right = reconstruct_tree(preorder_right_tree, inorder_right_tree) print('root={}'.format(root)) return root
def build_min_height_bst_from_sorted_subarray(start, end): if start >= end: return None mid = (start + end) // 2 return BstNode(A[mid], build_min_height_bst_from_sorted_subarray(start, mid), build_min_height_bst_from_sorted_subarray(mid + 1, end))
def bst_helper(A, start, end): if end < start: return None middle = (start + end) // 2 node = BstNode(A[middle]) node.left = bst_helper(A, start, middle - 1) node.right = bst_helper(A, middle + 1, end) return node
def helper(start, end): if end - start < 0: return None mid_idx = (end+start)//2 node = BstNode(A[mid_idx]) node.left = helper(start, mid_idx-1) node.right = helper(mid_idx+1, end) return node
def build_min_height_bst_from_sorted_array(A): if len(A) == 0: return None n = len(A) return BstNode(A[n // 2], build_min_height_bst_from_sorted_array(A[:n // 2]), build_min_height_bst_from_sorted_array(A[n // 2 + 1:]))
def build_min_height_bst_from_sorted_array(A): # SOS!!! check exactly the limits of the subarrays! if not A: return None head_idx = len(A) // 2 return BstNode(A[head_idx], build_min_height_bst_from_sorted_array(A[:head_idx]), build_min_height_bst_from_sorted_array(A[head_idx + 1:]))
def make(lower_bound, upper_bound): if index[0] == len(preorder_sequence): return None root = preorder_sequence[index[0]] if not lower_bound <= root <= upper_bound: return None index[0] += 1 L = make(lower_bound, root) R = make(root, upper_bound) return BstNode(root, L, R)
def build_bst(start=0, end=len(A)-1): if start > end: return None m = (start + end) // 2 left = build_bst(start, m - 1) right = build_bst(m + 1, end) return BstNode(A[m], left, right)
def rebuild_bst_from_preorder(preorder_sequence): if len(preorder_sequence) == 0: return None root = BstNode(preorder_sequence[0]) i = 1 left = [x for x in preorder_sequence[1:] if x < preorder_sequence[0]] right = [x for x in preorder_sequence[1:] if x > preorder_sequence[0]] root.left = rebuild_bst_from_preorder(left) root.right = rebuild_bst_from_preorder(right) return root
def build_min_height_bst_from_sorted_array(A: List[int]) -> Optional[BstNode]: root = None if len(A) != 0: middle = len(A) // 2 root = BstNode(A[middle]) left_arr = A[:middle] right_arr = A[middle + 1:] root.left = build_min_height_bst_from_sorted_array(left_arr) root.right = build_min_height_bst_from_sorted_array(right_arr) return root
def rebuild_bst_from_preorder(preorder_sequence): if not preorder_sequence: return None transition_point = next((i for i, a in enumerate(preorder_sequence) if a > preorder_sequence[0]), len(preorder_sequence)) return BstNode( preorder_sequence[0], rebuild_bst_from_preorder(preorder_sequence[1:transition_point]), rebuild_bst_from_preorder(preorder_sequence[transition_point:]))
def rebuild_bst_from_preorder(preorder_sequence): if not preorder_sequence: return None point = next((i for i, val in enumerate(preorder_sequence) if val > preorder_sequence[0]), len(preorder_sequence)) return BstNode(preorder_sequence[0], rebuild_bst_from_preorder(preorder_sequence[1:point]), rebuild_bst_from_preorder(preorder_sequence[point:]))
def build_min_height_bst_from_sorted_array(A: List[int]) -> Optional[BstNode]: if len(A) == 0: return None root_idx = len(A) // 2 root = A[root_idx] left_list = A[:root_idx] right_list = A[root_idx + 1:] left_subtree = build_min_height_bst_from_sorted_array(left_list) right_subtree = build_min_height_bst_from_sorted_array(right_list) return BstNode(root, left_subtree, right_subtree)
def build_min_height_bst_from_sorted_subarray(start, end): if start > end: return None mid = (start + end) // 2 tree = BstNode(A[mid]) tree.left = build_min_height_bst_from_sorted_subarray(start, mid - 1) tree.right = build_min_height_bst_from_sorted_subarray(mid + 1, end) return tree
def helper(root_idx, lower_bound, upper_bound): if root_idx >= len(preorder_sequence): return None elif not lower_bound <= preorder_sequence[root_idx] <= upper_bound: return None root = preorder_sequence[root_idx] root_idx += 1 return BstNode( root, helper(root_idx, lower_bound, root), helper(root_idx, root, upper_bound), )
def build_tree(A): if not A: return None mid_i = (len(A) - 1) // 2 mid_elem = A[mid_i] node = BstNode(mid_elem) node.left = build_tree(A[:mid_i]) node.right = build_tree(A[mid_i + 1:]) return node
def helper(left_limit, right_limit): nonlocal idx nonlocal arr if idx >= len(arr) or not left_limit < arr[idx] < right_limit: return None node = BstNode(data=arr[idx]) idx += 1 node.left = helper(left_limit, node.data) node.right = helper(node.data, right_limit) return node
def preorder_helper(lower_bound, upper_bound): if root_idx[0] == len(preorder_sequence): return None root = preorder_sequence[root_idx[0]] if not lower_bound <= root <= upper_bound: return None root_idx[0] += 1 node = BstNode(root) ## ordering is critical node.left = preorder_helper(lower_bound, root) node.right = preorder_helper(root, upper_bound) return node
def rebuild_bst_from_preorder( preorder_sequence: List[int]) -> Optional[BstNode]: if len(preorder_sequence) == 0: return None root = BstNode(preorder_sequence[0]) searchPath = deque([root], maxlen=len(preorder_sequence)) i = 1 while i < len(preorder_sequence): if preorder_sequence[i] < preorder_sequence[i - 1]: node = BstNode(preorder_sequence[i]) searchPath[-1].left = node searchPath.append(node) else: node = searchPath.pop() while len( searchPath) and searchPath[-1].data < preorder_sequence[i]: node = searchPath.pop() right = BstNode(preorder_sequence[i]) node.right = right searchPath.append(right) i += 1 return root
def build_min_height_bst_from_sorted_array(A): # TODO - you fill in here. # Alok if not A: return None splitIndex = len(A)//2 root = BstNode(A[splitIndex]) root.left = build_min_height_bst_from_sorted_array(A[:splitIndex]) root.right = build_min_height_bst_from_sorted_array(A[splitIndex+1:]) return root
def rebuild_within_range(low=float('-inf'), high=float('inf')): nonlocal i if i >= len(preorder_sequence): return None v = preorder_sequence[i] if low <= v <= high: u = BstNode(v) i += 1 u.left = rebuild_within_range(low=low, high=v) u.right = rebuild_within_range(low=v, high=high) return u return None
def construct_tree(root_idx, lower_bound, upper_bound): if root_idx == len(preorder_sequence): return Result(None, root_idx) root_val = preorder_sequence[root_idx] if not lower_bound <= root_val <= upper_bound: return Result(None, root_idx) root_idx += 1 tree = BstNode(root_val) tree.left, root_idx = construct_tree(root_idx, lower_bound, root_val) tree.right, root_idx = construct_tree(root_idx, root_val, upper_bound) return Result(tree, root_idx)
def build_bst(seq, start, end): if start == end: return None node = BstNode(seq[start]) right = start while right < end and seq[right] <= seq[start]: right += 1 node.left = build_bst(seq, start + 1, right) node.right = build_bst(seq, right, end) return node
def reconstruct(lower_bound, upper_bound): if root_idx[0] == len(preorder_sequence): return None root = preorder_sequence[root_idx[0]] if not (lower_bound < root < upper_bound): return None root_idx[0] += 1 left_subtree = reconstruct(lower_bound, root) right_subtree = reconstruct(root, upper_bound) return BstNode(root, left_subtree, right_subtree)
def rebuild_bst_from_preorder_on_value_range(lower_bound, upper_bound): if root_idx[0] == len(preorder_sequence): return None root = preorder_sequence[root_idx[0]] if not lower_bound <= root <= upper_bound: return None root_idx[0] += 1 left_subtree = rebuild_bst_from_preorder_on_value_range( lower_bound, root) right_subtree = rebuild_bst_from_preorder_on_value_range( root, upper_bound) return BstNode(root, left_subtree, right_subtree)
def rebuild_bst_from_preorder_on_value_range(lower_bound, upper_bound): if root_idx[0] == len(preorder_sequence): return None root = preorder_sequence[root_idx[0]] if not lower_bound <= root <= upper_bound: return None root_idx[0] += 1 # Note that rebuild_bst_from_preorder_on_value_range updates root_idx[0] # So the order of following two calls are critical left_subtree = rebuild_bst_from_preorder_on_value_range( lower_bound, root) right_subtree = rebuild_bst_from_preorder_on_value_range( root, upper_bound) return BstNode(root, left_subtree, right_subtree)
def merge_two_sorted_lists(A, B): sorted_head = BstNode() tail = sorted_head AB = [A, B] while all(AB): A_or_B = 0 if AB[0].data < AB[1].data else 1 tail.right = AB[A_or_B] tail = tail.right # Resets tail to the last node. AB[A_or_B] = tail.right if AB[0]: # Appends the remaining of A. tail.right = AB[0] elif AB[1]: # Appends the remaining of B. tail.right = AB[1] return sorted_head.right