Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions 617/memo.md
Original file line number Diff line number Diff line change
@@ -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 で表現してみました。



20 changes: 20 additions & 0 deletions 617/sol1.py
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions 617/sol2.py
Original file line number Diff line number Diff line change
@@ -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
32 changes: 32 additions & 0 deletions 617/sol3.py
Original file line number Diff line number Diff line change
@@ -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