From 83fc1525968c402590c372fc64b1a6a81e9b8807 Mon Sep 17 00:00:00 2001 From: bt3gl <138340846+bt3gl-cryptographer@users.noreply.github.com> Date: Tue, 8 Aug 2023 14:43:01 -0700 Subject: [PATCH] Update README.md --- trees/README.md | 253 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 222 insertions(+), 31 deletions(-) diff --git a/trees/README.md b/trees/README.md index 47b1c79..b2afbc9 100644 --- a/trees/README.md +++ b/trees/README.md @@ -60,7 +60,7 @@ def max_depth(root) -> int: ```python def height(root): - if not root: + if root is none: return 0 return 1 + max(height(root.left), height(root.right)) @@ -90,9 +90,6 @@ def bfs_iterative(root): result = [] queue = collections.deque([root]) - if root is None: - return result - while queue: node = queue.popleft() @@ -104,22 +101,6 @@ def bfs_iterative(root): return result - -def bfs_recursive(root) -> list: - - result = [] - if root is None: - return root - - def helper(node): - - if node: - result.append(node.val) - helper(node.left) - helper(node.right) - - helper(root) - return result ```
@@ -155,6 +136,24 @@ def inorder(root): if root is None: return [] return inorder(root.left) + [root.val] + inorder(root.right) + +def inorder_iterative(root) -> list: + + result = [] + stack = [] + node = root + + while stack or node: + + if node: + stack.append(node) + node = node.left + else: + node = stack.pop() + result.append(node.val) + node = node.right + + return result ````
@@ -171,10 +170,27 @@ def inorder(root):
```python -def preorder(root): +def preorder_recursive(root): if root is None: return [] return [root.val] + preorder(root.left) + preorder(root.right) + + +def preorder_iterative(root) -> list: + + result = [] + stack = [root] + + while stack: + + node = stack.pop() + + if node: + result.append(node.val) + stack.append(node.right) # not the order (stacks are fifo) + stack.append(node.left) + + return result ``` @@ -197,30 +213,204 @@ def preorder(root): def postorder(root): if root is None: return [] - return postorder(root.left) + postorder(root.right) + [root.val] + return postorder(root.left) + postorder(root.right) + [root.val] + + +def postorder_iterative(root) -> list: + stack, result = [], [] + node = root + + while node or stack: + + while node: + if node.right: + stack.append(node.right) + stack.append(node) + node = node.left + + node = stack.pop() + + if stack and node.right == stack[-1]: + stack[-1] = node + node = node.right + + else: + result.append(node.val) + node = None + + return result ``` - -
- ---- -### find height +### is same tree?
```python -def height(root): - if not root: - return -1 - return 1 + max(height(root.left), height(root.right)) +def is_same_trees(p, q): + + if not p and not q: + return True + + if (not p and q) or (not q and p): + return False + + if p.val != q.val: + return False + + return is_same_trees(p.right, q.right) and is_same_trees(p.left, q.left) ````
+--- + +### is symmetric? + +
+ +```python +def is_symmetric(root) -> bool: + + stack = [(root, root)] + + while stack: + + node1, node2 = stack.pop() + + if (not node1 and node2) or (not node2 and node1): + return False + + if node1 and node2: + + if node1.val != node2.val: + return False + + stack.append([node1.left, node2.right]) + stack.append([node1.right, node2.left]) + + return True + + +def is_symmetric_recursive(root) -> bool: + + def helper(node1, node2): + if (not node1 and node2) or \ + (not node2 and node1) or \ + (node1 and node2 and node1.val != node2.val): + return False + + if (not node1 and not node2): + return True + + return helper(node1.left, node2.right) and helper(node2.left, node1.right) + + return helper(root.left, root.right) +``` + +
+ +--- + +### lowest common ancestor + +
+ +```python +def lowest_common_ancestor(root, p, q): + + stack = [root] + parent = {root: None} + + while p not in parent or q not in parent: + + node = stack.pop() + if node: + parent[node.left] = node + parent[node.right] = node + stack.append(node.left) + stack.append(node.right) + + ancestors = set() + while p: + ancestors.add(p) + p = parent[p] + + while q not in ancestors: + q = parent[q] + + return q +``` + +
+ +--- + +### has path sum? + +
+ + +```python +def has_path_sum(root, target_sum) -> bool: + + def transverse(node, sum_here=0): + + if not node: + return sum_here == target_sum + + sum_here += node.val + + if not node.left: + return transverse(node.right, sum_here) + if not node.right: + return transverse(node.left, sum_here) + else: + return transverse(node.left, sum_here) or transverse(node.right, sum_here) + + if not root: + return False + + return transverse(root) +``` + +
+ +--- + +### build tree from preorder and inorder + +
+ +```python +def build_tree(preorder, inorder) -> Optional[Node]: + + def helper(left, right, index_map): + + if left > right: + return None + + root = Node(preorder.pop(0)) + index_here = index_map[root.val] + + # this order change from postorder + root.left = helper(left, index_here - 1, index_map) + root.right = helper(index_here + 1, right, index_map) + + return root + + index_map = {value: i for i, value in enumerate(inorder)} + + return helper(0, len(inorder) - 1, index_map) +``` + +
+ + ---- ### binary search trees @@ -228,7 +418,8 @@ def height(root):
* **binary search tree** are binary trees where all nodes on the left are smaller than the root, which is smaller than all nodes on the right. -* if a bst is **balanced**, it guarantees `O(log(N))` for insert and search (as we keep the tree's height as `H = log(N)`). common types of balanced trees: **red-black** and **avl**. +* if a bst is **balanced**, it guarantees `O(log(N))` for insert and search (as we keep the tree's height as `h = log(N)`). +* common types of balanced trees are **red-black** and **avl**.