-
Notifications
You must be signed in to change notification settings - Fork 0
【Arai60】23問目 617_Merge Two Binary Trees #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| # DFS(破壊的) | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
| if not root1 and not root2: | ||
| return None | ||
| if not root2: | ||
| return root1 | ||
| if not root1: | ||
| return root2 | ||
| root1.val += root2.val | ||
| root1.left = self.mergeTrees(root1.left, root2.left) | ||
| root1.right = self.mergeTrees(root1.right, root2.right) | ||
| return root1 | ||
|
|
||
|
|
||
| # BFS(破壊的) | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
|
|
||
| if not root1: | ||
| return root2 | ||
| if not root2: | ||
| return root1 | ||
| nodes_queue = deque([(root1, root2)]) | ||
| root1.val += root2.val | ||
| while nodes_queue: | ||
| node1, node2 = nodes_queue.popleft() | ||
| if node1.left and node2.left: | ||
| node1.left.val += node2.left.val | ||
| nodes_queue.append((node1.left, node2.left)) | ||
| if not node1.left: | ||
| node1.left = node2.left | ||
| if node1.right and node2.right: | ||
| node1.right.val += node2.right.val | ||
| nodes_queue.append((node1.right, node2.right)) | ||
| if not node1.right: | ||
| node1.right = node2.right | ||
| return root1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # DFS | ||
| # 非破壊的に修正 | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
| def helper_merge_trees(node1, node2): | ||
| if not node1 and not node2: | ||
| return None | ||
| if not node2: | ||
| return node1 | ||
| if not node1: | ||
| return node2 | ||
| node1.val += node2.val | ||
| node1.left = helper_merge_trees(node1.left, node2.left) | ||
| node1.right = helper_merge_trees(node1.right, node2.right) | ||
| return node1 | ||
|
|
||
| sum_tree = deepcopy(root1) | ||
| return helper_merge_trees(sum_tree, root2) | ||
|
|
||
|
|
||
| # BFS | ||
| # 非破壊的に修正 | ||
| # nodeの結合を関数化 | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
|
|
||
| def merge_nodes(node1, node2, queue): | ||
| if node1 and node2: | ||
| node1.val += node2.val | ||
| queue.append((node1, node2)) | ||
| if not node1: | ||
| node1 = node2 | ||
| return node1, queue | ||
|
|
||
| nodes_queue = deque() | ||
| sum_tree = deepcopy(root1) | ||
| sum_tree, nodes_queue = merge_nodes(sum_tree, root2, nodes_queue) | ||
| while nodes_queue: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なんかものすごく読みづらいんですよね。queueを引数で取り回しているからですかね?
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 確かに変な書き方になっている気がします。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. メインのwhileループで1番気になるのが、queueのライフサイクル(いつ取り出されていつ何が入ってくるのか)だと思うんですけど、関数の中でやってしまうとそこが追いづらいのがあるのかなと思います。 うーん、書いてみたんですけどあんまり良くなっていないかもです。二分木で親と子の繋ぎ変えが発生する場合はBFSだと書きにくいですね。 class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
def merge_nodes(node1, node2):
if not node1:
return copy.deepcopy(node2)
if not node2:
return node1
node1.val += node2.val
return node1
root1_clone = copy.deepcopy(root1)
merged_tree_root = merge_nodes(root1_clone, root2)
queue = deque()
if root1_clone and root2:
queue.append((root1_clone, root2))
while queue:
node1, node2 = queue.popleft()
# 本当はqueueへの追加と左右のマージの処理の順番は逆にしたいがnode1.left, node1.rightを書き換えるのでこの順番でないといけない。
if node1.left and node2.left:
queue.append((node1.left, node2.left))
if node1.right and node2.right:
queue.append((node1.right, node2.right))
node1.left = merge_nodes(node1.left, node2.left)
node1.right = merge_nodes(node1.right, node2.right)
return merged_tree_root
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。 |
||
| node1, node2 = nodes_queue.popleft() | ||
| node1.left, nodes_queue = merge_nodes(node1.left, node2.left, nodes_queue) | ||
| node1.right, nodes_queue = merge_nodes(node1.right, node2.right, nodes_queue) | ||
| return sum_tree | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
| def helper_merge_tree(node1, node2): | ||
| if not node1 and not node2: | ||
| return None | ||
| if not node1: | ||
| return node2 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. root2をルートとするツリーについては、引数で渡ってきたものをそのまま使用しているので、この書き方だとmergeTreesの返り値のTreeにroot2の一部が使われてしまいます。この関数自体では非破壊的かもしれないですが、mergeTreesの返り値のTreeの操作を行うとroot2のツリーを書き換えてしまう可能性があります。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 返り値のTreeが中途半端でたちが悪くなっていることに気づきませんでした。 |
||
| if not node2: | ||
| return node1 | ||
| node1.val += node2.val | ||
| node1.left = helper_merge_tree(node1.left, node2.left) | ||
| node1.right = helper_merge_tree(node1.right, node2.right) | ||
| return node1 | ||
|
|
||
| sum_tree = deepcopy(root1) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sum_treeの命名がなんか気になります。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. コピーした時点では |
||
| return helper_merge_tree(sum_tree, root2) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # DFS(非破壊) | ||
| # レビューコメントを反映 | ||
| # helper関数をなくした | ||
| class Solution: | ||
| def mergeTrees( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ヘルパー関数なしでも書けそうですね。 |
||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
| if not root2: | ||
| return deepcopy(root1) | ||
| if not root1: | ||
| return deepcopy(root2) | ||
| node = TreeNode(root1.val + root2.val) | ||
| node.left = self.mergeTrees(root1.left, root2.left) | ||
| node.right = self.mergeTrees(root1.right, root2.right) | ||
| return node | ||
|
|
||
| # BFS(非破壊) | ||
| # レビューコメントを反映 | ||
| class Solution: | ||
| def mergeTrees( | ||
| self, root1: Optional[TreeNode], root2: Optional[TreeNode] | ||
| ) -> Optional[TreeNode]: | ||
|
|
||
| def merge_nodes(node1, node2): | ||
| if not node2: | ||
| return deepcopy(node1) | ||
| if not node1: | ||
| return deepcopy(node2) | ||
| new_node = TreeNode(node1.val + node2.val) | ||
| return new_node | ||
|
|
||
| merged_root = merge_nodes(root1, root2) | ||
| nodes_queue = deque() | ||
| if root1 and root2: | ||
| nodes_queue.append((merged_root, root1, root2)) | ||
| while nodes_queue: | ||
| merged_node, node1, node2 = nodes_queue.popleft() | ||
| merged_node.left = merge_nodes(node1.left, node2.left) | ||
| merged_node.right = merge_nodes(node1.right, node2.right) | ||
| if node1.left and node2.left: | ||
| nodes_queue.append((merged_node.left, node1.left, node2.left)) | ||
| if node1.right and node2.right: | ||
| nodes_queue.append((merged_node.right, node1.right, node2.right)) | ||
| return merged_root | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このif文はなくても動くと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不要なif文でしたので削除します。
解法が整理しきれてませんでしたね。