From 06be37c56a2edc00397c03a0e08411e8b696a70b Mon Sep 17 00:00:00 2001 From: tom4649 Date: Mon, 16 Mar 2026 15:36:50 +0900 Subject: [PATCH] 617. Merge Two Binary Trees --- 617/memo.md | 25 +++++++++++++++++++++++++ 617/sol1.py | 20 ++++++++++++++++++++ 617/sol2.py | 23 +++++++++++++++++++++++ 617/sol3.py | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 617/memo.md create mode 100644 617/sol1.py create mode 100644 617/sol2.py create mode 100644 617/sol3.py diff --git a/617/memo.md b/617/memo.md new file mode 100644 index 0000000..399900b --- /dev/null +++ b/617/memo.md @@ -0,0 +1,25 @@ +# 617. Merge Two Binary Trees +- https://leetcode.com/problems/merge-two-binary-trees/description/ +- sol1.py: 再帰で書いた。Noneの場合分けをわずかに工夫したつもりではいる。 + - 他の人のコードを読んで、このコードは破壊的であることを認識した。自分で気にできるようになりたい。 +- sol2.py: 非破壊的になるように書いた + - 速度は遅くなった +- https://github.com/Shoichifunyu/shofun/pull/17/changes + - mergeTreesの内側に関数を定義する必要はないだろう + - nodeのNone処理は似ている(真似てはいない) +- https://github.com/mamo3gr/arai60/blob/617_merge-two-binary-trees/617_merge-two-binary-trees/memo.md + - https://docs.python.org/3.13/library/copy.html + - deepcopyは新しいオブジェクトのコピーを挿入する + - 複合オブジェクトでない場合には違いは生じない +> 浅いコピー (shallow copy) は新たな複合オブジェクトを作成し、その後 (可能な限り) 元のオブジェクト中に見つかったオブジェクトに対する 参照 を挿入します。 +> 深いコピー (deep copy) は新たな複合オブジェクトを作成し、その後元のオブジェクト中に見つかったオブジェクトの コピー を挿入します。 + +- stackを用いた解法 + - https://github.com/tarinaihitori/leetcode/pull/23/changes/BASE..3661cef8b334d992a50e919393c5db1b8e22f9e0#diff-1ede2b2a752e6743ca4d35b115594d80caecd186a464943ab76618d8d1811252 + - 部分関数を使ってpythonでポインタを実装している + - 面白いので写経してみる +> Python は、メンバ変数へのポインターが持てないので、どうしても繰り返し感がでますね。下のような方法は一応考えてみました。 +> これも別に良いコードではないですが、C++ だとどこに書き込むかをスタックに積むことができるので、少し簡単になるのです。それを擬似的に Python で表現してみました。 + + + diff --git a/617/sol1.py b/617/sol1.py new file mode 100644 index 0000000..c6d96bc --- /dev/null +++ b/617/sol1.py @@ -0,0 +1,20 @@ +# 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 root1 is None and root2 is None: + return None + if root1 is None: + root1, root2 = root2, root1 + if root2 is None: + return root1 + merged = TreeNode(val=root1.val + root2.val) + merged.left = self.mergeTrees(root1.left, root2.left) + merged.right = self.mergeTrees(root1.right, root2.right) + return merged diff --git a/617/sol2.py b/617/sol2.py new file mode 100644 index 0000000..06e750f --- /dev/null +++ b/617/sol2.py @@ -0,0 +1,23 @@ +import copy + + +# 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 root1 is None and root2 is None: + return None + if root1 is None: + root1, root2 = root2, root1 + if root2 is None: + return copy.deepcopy(root1) + merged = TreeNode(val=root1.val + root2.val) + merged.left = self.mergeTrees(root1.left, root2.left) + merged.right = self.mergeTrees(root1.right, root2.right) + return merged diff --git a/617/sol3.py b/617/sol3.py new file mode 100644 index 0000000..8849159 --- /dev/null +++ b/617/sol3.py @@ -0,0 +1,32 @@ +from collections import deque +from functools import partial + + +# 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]: + stack = deque() + dummy = TreeNode() + stack.append((partial(setattr, dummy, "left"), [root1, root2])) + while stack: + set_func, roots = stack.pop() + filtered_roots = [r for r in roots if r] + if not filtered_roots: + continue + new_root = TreeNode(sum([r.val for r in filtered_roots])) + set_func(new_root) + for child in ["left", "right"]: + stack.append( + ( + partial(setattr, new_root, child), + [getattr(r, child) for r in roots if r], + ) + ) + return dummy.left