From ef6ede57072372b861c786a37a8bb024dbc746f3 Mon Sep 17 00:00:00 2001 From: harman-02 Date: Wed, 25 Oct 2023 14:48:47 +0530 Subject: [PATCH 1/5] Added least common ancestor's code --- trees/least_common_ancestor.py | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 trees/least_common_ancestor.py diff --git a/trees/least_common_ancestor.py b/trees/least_common_ancestor.py new file mode 100644 index 000000000000..3c137452e993 --- /dev/null +++ b/trees/least_common_ancestor.py @@ -0,0 +1,53 @@ +class TreeNode: + def __init__(self, data, left=None, right=None): + self.data = data + self.left = left + self.right = right + + +def insert(temp, data): + que = [temp] + while len(que): + temp = que[0] + que.pop(0) + if not temp.left: + if data is not None: + temp.left = TreeNode(data) + else: + temp.left = TreeNode(0) + break + else: + que.append(temp.left) + if not temp.right: + if data is not None: + temp.right = TreeNode(data) + else: + temp.right = TreeNode(0) + break + else: + que.append(temp.right) + + +def make_tree(elements): + Tree = TreeNode(elements[0]) + for element in elements[1:]: + insert(Tree, element) + return Tree + + +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + if not root: + return None + if root.data == p or root.data == q: + return root + left = self.lowestCommonAncestor(root.left, p, q) + right = self.lowestCommonAncestor(root.right, p, q) + if right and left: + return root + return right or left + + +ob1 = Solution() +tree = make_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) +print(ob1.lowestCommonAncestor(tree, 5, 1).data) From 5a8ce130a4da18f5b32cdf8db02ba3d8a20b6c8a Mon Sep 17 00:00:00 2001 From: harman-02 Date: Wed, 25 Oct 2023 16:37:20 +0530 Subject: [PATCH 2/5] Added least common ancestor's code --- trees/least_common_ancestor.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/trees/least_common_ancestor.py b/trees/least_common_ancestor.py index 3c137452e993..d106ecf17e27 100644 --- a/trees/least_common_ancestor.py +++ b/trees/least_common_ancestor.py @@ -29,20 +29,20 @@ def insert(temp, data): def make_tree(elements): - Tree = TreeNode(elements[0]) + tree = TreeNode(elements[0]) for element in elements[1:]: - insert(Tree, element) - return Tree + insert(tree, element) + return tree -class Solution(object): - def lowestCommonAncestor(self, root, p, q): +class Solution: + def lowestcommonancestor(self, root, p, q): if not root: return None - if root.data == p or root.data == q: + if root.data in (p, q): return root - left = self.lowestCommonAncestor(root.left, p, q) - right = self.lowestCommonAncestor(root.right, p, q) + left = self.lowestcommonancestor(root.left, p, q) + right = self.lowestcommonancestor(root.right, p, q) if right and left: return root return right or left @@ -50,4 +50,4 @@ def lowestCommonAncestor(self, root, p, q): ob1 = Solution() tree = make_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) -print(ob1.lowestCommonAncestor(tree, 5, 1).data) +print(ob1.lowestcommonancestor(tree, 5, 1).data) From 2d644ae35b8a995fc72bae947e18d08c6ed6f306 Mon Sep 17 00:00:00 2001 From: harman-02 Date: Wed, 25 Oct 2023 16:38:27 +0530 Subject: [PATCH 3/5] Added least common ancestor's code --- trees/least_common_ancestor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trees/least_common_ancestor.py b/trees/least_common_ancestor.py index d106ecf17e27..65e20a36ebde 100644 --- a/trees/least_common_ancestor.py +++ b/trees/least_common_ancestor.py @@ -29,10 +29,10 @@ def insert(temp, data): def make_tree(elements): - tree = TreeNode(elements[0]) + tr = TreeNode(elements[0]) for element in elements[1:]: - insert(tree, element) - return tree + insert(tr, element) + return tr class Solution: From 2047f53565d893805e10af99ad04a49c01ffb4b6 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 29 Oct 2023 13:35:07 +0100 Subject: [PATCH 4/5] Update least_common_ancestor.py --- trees/least_common_ancestor.py | 109 +++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 24 deletions(-) diff --git a/trees/least_common_ancestor.py b/trees/least_common_ancestor.py index 65e20a36ebde..0c93f9d4d2fc 100644 --- a/trees/least_common_ancestor.py +++ b/trees/least_common_ancestor.py @@ -1,53 +1,114 @@ -class TreeNode: - def __init__(self, data, left=None, right=None): - self.data = data - self.left = left - self.right = right +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass + + +@dataclass +class Node: + """ + A node in a binary tree. + >>> Node(0) + Node(data=0, left=None, right=None) + >>> Node(0, Node(1), Node(2)) # doctest: +NORMALIZE_WHITESPACE + Node(data=0, + left=Node(data=1, left=None, right=None), + right=Node(data=2, left=None, right=None)) + """ + + data: int + left: Node | None = None + right: Node | None = None + + def __iter__(self) -> Iterator[int]: + """ + >>> list(Node(0)) + [0] + >>> tuple(Node(1, Node(0), Node(2))) + (0, 1, 2) + """ + if self.left: + yield from self.left + yield self.data + if self.right: + yield from self.right + + def __len__(self) -> int: + """ + >>> len(Node(0)) + 1 + >>> len(Node(1, Node(0), Node(2))) + 3 + """ + return sum(1 for _ in self) def insert(temp, data): + """ + Insert a node into a binary tree. + >>> root = Node(1) + >>> insert(root, 0) + >>> tuple(root) + (0, 1) + >>> insert(root, 2) + >>> tuple(root) + (0, 1, 2) + """ que = [temp] while len(que): temp = que[0] que.pop(0) if not temp.left: if data is not None: - temp.left = TreeNode(data) + temp.left = Node(data) else: - temp.left = TreeNode(0) + temp.left = Node(0) break else: que.append(temp.left) if not temp.right: if data is not None: - temp.right = TreeNode(data) + temp.right = Node(data) else: - temp.right = TreeNode(0) + temp.right = Node(0) break else: que.append(temp.right) def make_tree(elements): - tr = TreeNode(elements[0]) + """ + Insert nodes into a binary tree. + >>> tuple(make_tree(range(10))) + (7, 3, 8, 1, 9, 4, 0, 5, 2, 6) + """ + tr = Node(elements[0]) for element in elements[1:]: insert(tr, element) return tr -class Solution: - def lowestcommonancestor(self, root, p, q): - if not root: - return None - if root.data in (p, q): - return root - left = self.lowestcommonancestor(root.left, p, q) - right = self.lowestcommonancestor(root.right, p, q) - if right and left: - return root - return right or left +def lowest_common_ancestor(root, p, q): + """ + >>> tree = make_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) + >>> lowest_common_ancestor(tree, 5, 1).data + 3 + """ + if not root: + return None + if root.data in (p, q): + return root + left = lowest_common_ancestor(root.left, p, q) + right = lowest_common_ancestor(root.right, p, q) + if right and left: + return root + return right or left + +if __name__ == "__main__": + import doctest -ob1 = Solution() -tree = make_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) -print(ob1.lowestcommonancestor(tree, 5, 1).data) + doctest.testmod() + tree = make_tree([3, 5, 1, 6, 2, 0, 8, None, None, 7, 4]) + print(f"{tuple(tree) = }") + print(f"{lowest_common_ancestor(tree, 5, 1).data = }") From 5dc5a237348282cb4472d8d04b8b4d07f4766fb0 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 29 Oct 2023 13:36:02 +0100 Subject: [PATCH 5/5] Rename trees/least_common_ancestor.py to data_structures/binary_tree/least_common_ancestor.py --- {trees => data_structures/binary_tree}/least_common_ancestor.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {trees => data_structures/binary_tree}/least_common_ancestor.py (100%) diff --git a/trees/least_common_ancestor.py b/data_structures/binary_tree/least_common_ancestor.py similarity index 100% rename from trees/least_common_ancestor.py rename to data_structures/binary_tree/least_common_ancestor.py