From 40ddb348b64af9c57b511d9f7241fe53212ba959 Mon Sep 17 00:00:00 2001 From: kazukiii Date: Tue, 9 Jul 2024 01:59:31 -0700 Subject: [PATCH 1/2] =?UTF-8?q?step1,=20step2,=20step3=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/merge-two-binary-trees/README.md | 36 ++++++++++++++++ arai60/merge-two-binary-trees/step1.py | 40 ++++++++++++++++++ arai60/merge-two-binary-trees/step2.py | 16 ++++++++ .../step2_nonrecursive.py | 41 +++++++++++++++++++ arai60/merge-two-binary-trees/step3.py | 16 ++++++++ 5 files changed, 149 insertions(+) create mode 100644 arai60/merge-two-binary-trees/README.md create mode 100644 arai60/merge-two-binary-trees/step1.py create mode 100644 arai60/merge-two-binary-trees/step2.py create mode 100644 arai60/merge-two-binary-trees/step2_nonrecursive.py create mode 100644 arai60/merge-two-binary-trees/step3.py diff --git a/arai60/merge-two-binary-trees/README.md b/arai60/merge-two-binary-trees/README.md new file mode 100644 index 0000000..818284f --- /dev/null +++ b/arai60/merge-two-binary-trees/README.md @@ -0,0 +1,36 @@ +## 考察 +- 初見の問題 +- 方針 + - DFS/BFS + - 全ノードを探索しながら新しい二分木を生成して返すのが思い付く + - どちらかの二分木を再利用もできそうだが、新しい二分木を作る方を選択 + - Pythonで関数からの戻り値をいじったら、他のところが壊れましたはびっくりしそう +- 再帰の最大深さが2000だが、まずは再帰で書いてみる +- Step2で非再帰に書き直そうと思う +- あとは実装 + +## Step1 +- 再帰DFSで実装 +- time: O(n), space: O(n) + +## Step2 +- 非再帰に書き換え + - 3点を書き換えた + - popの位置に再帰関数の処理を持ってくる + - 再帰呼び出しをstackへのappendに変更 + - returnをcontinueへ変更 + - stack -> queueとすればBFSにもなる +- 他の人のPRを検索 + - めちゃくちゃシンプル + - https://github.com/SuperHotDogCat/coding-interview/pull/35/files#diff-e23bfd258f7b29f3e94954b1beeca569cce5d7f3b17de6f3223729c1ebf588a5 + - 帰りがけで下から構築していくのは思い付かなかった... + - これならhelperも作る必要ない + - こちらもめちゃくちゃシンプル + - https://github.com/fhiyo/leetcode/pull/25 + - 行きがけで書くにしてももう少し条件を整理できそう +- 帰りがけDFSで実装してみる + +## Step3 +- 1回目: 1m36s +- 2回目: 1m15s +- 3回目: 1m17s diff --git a/arai60/merge-two-binary-trees/step1.py b/arai60/merge-two-binary-trees/step1.py new file mode 100644 index 0000000..d211ab2 --- /dev/null +++ b/arai60/merge-two-binary-trees/step1.py @@ -0,0 +1,40 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: + if not root1 and not root2: return None + if not root1: return TreeNode(root2.val) + if not root2: return TreeNode(root1.val) + + merged_root = TreeNode(root1.val + root2.val) + def merge_trees_helper(root1: Optional[TreeNode], root2: Optional[TreeNode], merged_root: TreeNode) -> None: + if not root1 and not root2: return + if not root1: + merged_root.left = deepcopy(root2.left) + merged_root.right = deepcopy(root2.right) + return + if not root2: + merged_root.left = deepcopy(root1.left) + merged_root.right = deepcopy(root1.right) + return + + if root1.left or root2.left: + left_sum = 0 + if root1.left: left_sum += root1.left.val + if root2.left: left_sum += root2.left.val + merged_root.left = TreeNode(left_sum) + merge_trees_helper(root1.left, root2.left, merged_root.left) + + if root1.right or root2.right: + right_sum = 0 + if root1.right: right_sum += root1.right.val + if root2.right: right_sum += root2.right.val + merged_root.right = TreeNode(right_sum) + merge_trees_helper(root1.right, root2.right, merged_root.right) + + merge_trees_helper(root1, root2, merged_root) + return merged_root diff --git a/arai60/merge-two-binary-trees/step2.py b/arai60/merge-two-binary-trees/step2.py new file mode 100644 index 0000000..b2a4170 --- /dev/null +++ b/arai60/merge-two-binary-trees/step2.py @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: + if not root1 and not root2: return None + if not root1: return deepcopy(root2) + if not root2: return deepcopy(root1) + + merged_root = TreeNode(root1.val + root2.val) + merged_root.left = self.mergeTrees(root1.left, root2.left) + merged_root.right = self.mergeTrees(root1.right, root2.right) + return merged_root diff --git a/arai60/merge-two-binary-trees/step2_nonrecursive.py b/arai60/merge-two-binary-trees/step2_nonrecursive.py new file mode 100644 index 0000000..347aadc --- /dev/null +++ b/arai60/merge-two-binary-trees/step2_nonrecursive.py @@ -0,0 +1,41 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: + if not root1 and not root2: return None + if not root1: return TreeNode(root2.val) + if not root2: return TreeNode(root1.val) + + merged_tree = TreeNode(root1.val + root2.val) + nodes_to_visit = [(root1, root2, merged_tree)] + while nodes_to_visit: + root1, root2, merged_root = nodes_to_visit.pop() + if not root1 and not root2: continue + if not root1: + merged_root.left = deepcopy(root2.left) + merged_root.right = deepcopy(root2.right) + continue + if not root2: + merged_root.left = deepcopy(root1.left) + merged_root.right = deepcopy(root1.right) + continue + + if root1.left or root2.left: + left_sum = 0 + if root1.left: left_sum += root1.left.val + if root2.left: left_sum += root2.left.val + merged_root.left = TreeNode(left_sum) + nodes_to_visit.append((root1.left, root2.left, merged_root.left)) + + if root1.right or root2.right: + right_sum = 0 + if root1.right: right_sum += root1.right.val + if root2.right: right_sum += root2.right.val + merged_root.right = TreeNode(right_sum) + nodes_to_visit.append((root1.right, root2.right, merged_root.right)) + + return merged_tree diff --git a/arai60/merge-two-binary-trees/step3.py b/arai60/merge-two-binary-trees/step3.py new file mode 100644 index 0000000..b2a4170 --- /dev/null +++ b/arai60/merge-two-binary-trees/step3.py @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: + if not root1 and not root2: return None + if not root1: return deepcopy(root2) + if not root2: return deepcopy(root1) + + merged_root = TreeNode(root1.val + root2.val) + merged_root.left = self.mergeTrees(root1.left, root2.left) + merged_root.right = self.mergeTrees(root1.right, root2.right) + return merged_root From 3096a36f7b90f26d8caf484ec0a3fd2c1a45e755 Mon Sep 17 00:00:00 2001 From: kazukiii Date: Wed, 10 Jul 2024 00:47:39 -0700 Subject: [PATCH 2/2] =?UTF-8?q?bug=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/merge-two-binary-trees/step1.py | 4 ++-- arai60/merge-two-binary-trees/step2_nonrecursive.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arai60/merge-two-binary-trees/step1.py b/arai60/merge-two-binary-trees/step1.py index d211ab2..5e59d36 100644 --- a/arai60/merge-two-binary-trees/step1.py +++ b/arai60/merge-two-binary-trees/step1.py @@ -7,8 +7,8 @@ class Solution: def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: if not root1 and not root2: return None - if not root1: return TreeNode(root2.val) - if not root2: return TreeNode(root1.val) + if not root1: return deepcopy(root2) + if not root2: return deepcopy(root1) merged_root = TreeNode(root1.val + root2.val) def merge_trees_helper(root1: Optional[TreeNode], root2: Optional[TreeNode], merged_root: TreeNode) -> None: diff --git a/arai60/merge-two-binary-trees/step2_nonrecursive.py b/arai60/merge-two-binary-trees/step2_nonrecursive.py index 347aadc..2b99522 100644 --- a/arai60/merge-two-binary-trees/step2_nonrecursive.py +++ b/arai60/merge-two-binary-trees/step2_nonrecursive.py @@ -7,8 +7,8 @@ class Solution: def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: if not root1 and not root2: return None - if not root1: return TreeNode(root2.val) - if not root2: return TreeNode(root1.val) + if not root1: return deepcopy(root2) + if not root2: return deepcopy(root1) merged_tree = TreeNode(root1.val + root2.val) nodes_to_visit = [(root1, root2, merged_tree)]