From bb72bab679c56e1543df51d21b6b61770c9ae771 Mon Sep 17 00:00:00 2001 From: bt3gl <138340846+cypher-bt3gl@users.noreply.github.com> Date: Sat, 29 Jul 2023 14:28:17 -0700 Subject: [PATCH] add some fun tree playing --- trees_and_graphs/find_max_depth_tree.py | 6 ++ trees_and_graphs/has_path_sum.py | 21 ++++++ trees_and_graphs/is_tree_symmetric.py | 38 ++++++++++ trees_and_graphs/preorder_transversal.py | 28 ++++++++ trees_and_graphs/sum_2_numbers_with_bs.py | 86 +++++++++++++++++++++++ trees_and_graphs/tree_level_traversal.py | 30 ++++++++ 6 files changed, 209 insertions(+) create mode 100644 trees_and_graphs/find_max_depth_tree.py create mode 100644 trees_and_graphs/has_path_sum.py create mode 100644 trees_and_graphs/is_tree_symmetric.py create mode 100644 trees_and_graphs/preorder_transversal.py create mode 100644 trees_and_graphs/sum_2_numbers_with_bs.py create mode 100644 trees_and_graphs/tree_level_traversal.py diff --git a/trees_and_graphs/find_max_depth_tree.py b/trees_and_graphs/find_max_depth_tree.py new file mode 100644 index 0000000..c406629 --- /dev/null +++ b/trees_and_graphs/find_max_depth_tree.py @@ -0,0 +1,6 @@ +def max_depth(root: Optional[TreeNode]) -> int: + + if root is None: + return 0 + + return max(max_depth(root.left) + 1, max_depth(root.right) + 1) diff --git a/trees_and_graphs/has_path_sum.py b/trees_and_graphs/has_path_sum.py new file mode 100644 index 0000000..827f010 --- /dev/null +++ b/trees_and_graphs/has_path_sum.py @@ -0,0 +1,21 @@ +def has_path_sum(root: Optional[TreeNode], target_sum: int) -> 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) + diff --git a/trees_and_graphs/is_tree_symmetric.py b/trees_and_graphs/is_tree_symmetric.py new file mode 100644 index 0000000..f652fc0 --- /dev/null +++ b/trees_and_graphs/is_tree_symmetric.py @@ -0,0 +1,38 @@ +def is_symmetrical(root: Optional[TreeNode]) -> bool: + + stack = [(root, root)] + + while stack: + + node1, node2 = stack.pop() + + if (not node1 and node2) or (not node2 and node1): + return False + + elif not node1 and not node2: + continue + + elif node1 and node2 and node1.val != node2.val: + return False + + stack.append([node1.left, node2.right]) + stack.append([node1.right, node2.left]) + + return True + + +def is_symmetrical_recursive(root: Optional[TreeNode]) -> 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) + diff --git a/trees_and_graphs/preorder_transversal.py b/trees_and_graphs/preorder_transversal.py new file mode 100644 index 0000000..09c26d5 --- /dev/null +++ b/trees_and_graphs/preorder_transversal.py @@ -0,0 +1,28 @@ +# recursive and iterative inorder traversal + +def preorder_recursive(root: Optional[TreeNode]) -> list[int]: + + if root == None: + return [] + + return [root.val] + preorder_recursive(root.left) + preorder_recursive(root.right) + + +def preorder_iterative(root: Optional[TreeNode]) -> list[int]: + + result = [] + stack = [root] + + while stack: + + current = stack.pop() + result.append(current.val) + + if current.right: + stack.append(current.right) + + if current.left: + stack.append(current.left) + + return result + diff --git a/trees_and_graphs/sum_2_numbers_with_bs.py b/trees_and_graphs/sum_2_numbers_with_bs.py new file mode 100644 index 0000000..c45c5f4 --- /dev/null +++ b/trees_and_graphs/sum_2_numbers_with_bs.py @@ -0,0 +1,86 @@ +# given a collection of numbers, find the pair +# of numbers that sum to a given number + + + +def bs(array, desired_num): + + start = 0 + end = len(array) + mid = (end - start) // 2 + + while len(array) > 0: + if array[mid] == desired_num: + return True + elif array[mid] > desired_num: + return bs(array[mid+1:], desired_num) + else: + return bs(array[:mid], desired_num) + + return False + + +def find_pairs_bs(array, desired_sum): + + for i in range(len(array)): + num1 = array[i] + desired_num = desired_sum - num1 + if bs(array[i + 1:], desired_num) == True: + return (num1, desired_num) + + return False + + +def find_pairs_max_sum(array, desired_sum): + + i, j = 0, len(array) - 1 + + while i < j: + if array[i] + array[j] == desired_sum: + return array[i], array[j] + elif array[i] + array[j] > desired_sum: + j = j - 1 + elif array[i] + array[j] < desired_sum: + i = i + 1 + + return False + +def find_pairs_not_sorted(array, desired_sum): + + lookup = {} + + for item in array: + key = desired_sum - item + + if key in lookup.keys(): + lookup[key] += 1 + else: + lookup[key] = 1 + + for item in array: + key = desired_sum - item + + if item in lookup.keys(): + if lookup[item] == 1: + return (item, key) + else: + lookup[item] -= 1 + + return False + + + +if __name__ == "__main__": + + desired_sum = 8 + array1 = [1, 2, 3, 9] + array2 = [1, 2, 4, 5, 4] + array3 = [2, 1, 6, 3, 11, 2] + + assert(find_pairs_bs(array1, desired_sum) == False) + assert(find_pairs_bs(array2, desired_sum) == (4, 4)) + assert(find_pairs_max_sum(array1, desired_sum) == False) + assert(find_pairs_max_sum(array2, desired_sum) == (4,4)) + assert(find_pairs_not_sorted(array1, desired_sum) == False) + assert(find_pairs_not_sorted(array2, desired_sum) == (4, 4)) + assert(find_pairs_not_sorted(array3, desired_sum) == (2, 6)) diff --git a/trees_and_graphs/tree_level_traversal.py b/trees_and_graphs/tree_level_traversal.py new file mode 100644 index 0000000..0511113 --- /dev/null +++ b/trees_and_graphs/tree_level_traversal.py @@ -0,0 +1,30 @@ +# Given the root of a binary tree, return the level order traversal of its nodes' values. +# (i.e., from left to right, level by level). + + +def levelOrder(root: Optional[TreeNode]) -> list[list[int]]: + + if root is None: + return [] + + queue = collections.deque() + queue.append(root) + result = [] + + while queue: + + this_level = [] + + for _ in range(len(queue)): + + current = queue.popleft() + + if current: + this_level.append(current.val) + queue.append(current.left) + queue.append(current.right) + + if this_level: + result.append(this_level) + + return result