-
Notifications
You must be signed in to change notification settings - Fork 0
105.construct binary tree from preorder and inorder traversal #31
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
Open
xbam326
wants to merge
2
commits into
main
Choose a base branch
from
105
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
51 changes: 51 additions & 0 deletions
51
problems/105.construct-binary-tree-from-preorder-and-inorder-traversal/memo.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| ## step1 | ||
| - `preorder`,`inorder`がわからなかったのでChatGPTに聞いた。なんとなく思い出した。 | ||
| preorder: 根 → 左部分木 → 右部分木 | ||
| inorder: 左部分木 → 根 → 右部分木 | ||
| - 上の流れを見るとpreorderの先頭は常に現在のrootになっているのでそれをinorderで見つけるようにするとかすればいいのかもしれない | ||
| - step1. rootを見つける | ||
| - step2. leftを見つける | ||
| - preorderのrootの右隣がある場合はleftが存在 | ||
| - inorderのrootが出てきたところまでの中と一致するかどうか | ||
| - step3. rightを見つける | ||
| - inorderのrootの右隣が存在する場合はrightが存在 | ||
| - `preorder and inorder consist of unique values.`この条件が無い場合はめちゃ難しくなりそう | ||
| - 配列は1 <= preorder.length <= 3000なのでNoneの場合はなし | ||
| - 15分ほどで解けたがこれを分かりやすく読みやすく書くのは難しそう | ||
| - 値がuniqueではない場合を考えたが、エラーが出たら、rootのindexを見る際に+1番目を確認するという場当たり的なものしか浮かばなかった | ||
|
|
||
|
|
||
| ## step2 | ||
| - 時間計算量は最悪O(N^2)(全部left)で最良でO(N)(全部right),空間計算量はO(N) | ||
| - あらかじめinorderでvalue_to_indexを作っておくと常にO(N)にできる | ||
| - 他の人のコードをみる | ||
| - https://github.com/plushn/SWE-Arai60/pull/29/changes | ||
| - stackでの実装も可能 | ||
| - step1の`mid`という変数名は気になった(真ん中でない場合もあるため)rootとかparentとかの方が個人的にはしっくりくる | ||
| - step2の実装時に`TreeNode()`で初期化して後からvalを設定していくところも若干抵抗があった | ||
| - 最後まで読まないとこれで問題ないかどうかがわからないから | ||
| - https://github.com/mamo3gr/arai60/pull/28/changes | ||
| - `再帰で次に渡す配列は、コピーではなくインデックスにすると、メモリ使用量が減らせる`自分の解法は配列をcopyしていっているため空間計算量はO(N)ではなく、O(N^2)になっていた | ||
| - step1のコード見やすかった。下記は変数にした方が認知負荷を減らせそう。あとreturnの部分も最後に組み立てるイメージが湧いてわかりやすかった。 | ||
| ``` | ||
| inorder_left = inorder[:root_index] | ||
| inorder_right = inorder[root_index + 1 :] | ||
|
|
||
| preorder_left = preorder[1 : len(inorder_left) + 1] | ||
| preorder_right = preorder[len(inorder_left) + 1 :] | ||
| ``` | ||
| - dataclassを自分から使えないので選択肢に入れたい | ||
| - 再帰でないやり方もあるが今回は自分としては再帰の方がしっくりきた | ||
| - `インデックスの操作に苦戦する。いつまで経っても苦手だ、これ。`自分も毎回苦労しており、特にsliceの含む含まないをCLIの対話モードで確認しているが早く抜け出したい | ||
| - `array.array` を使うと、スライスをコピーしなくても書ける。 | ||
| - https://github.com/Yoshiki-Iwasa/Arai60/pull/33#discussion_r1688357607 | ||
| - https://docs.python.org/3.13/library/array.html | ||
| - `array.array`と番兵の部分が難しくて消化不良だが後から見返す | ||
| - https://github.com/naoto-iwase/leetcode/pull/34 | ||
| - 実装2のelseからが何をしているのかがわからなかった。。。 | ||
| - だいぶ消化不良だが、後からまた戻ってくるようにする | ||
| - step2ではdictに入れてindexの探索をO(N)でできるように改良する部分だけ対応する | ||
| - しようと思ったがそうすると再帰で配列のsliceを渡せなくなり難しいので諦める | ||
|
|
||
| ## step3 | ||
|
|
37 changes: 37 additions & 0 deletions
37
problems/105.construct-binary-tree-from-preorder-and-inorder-traversal/step1.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # | ||
| # @lc app=leetcode id=105 lang=python3 | ||
| # | ||
| # [105] Construct Binary Tree from Preorder and Inorder Traversal | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # 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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: | ||
| root_val = preorder[0] | ||
| root = TreeNode(preorder[0]) | ||
| root_index_at_inorder = inorder.index(root_val) | ||
|
|
||
| has_left = root_index_at_inorder != 0 | ||
| if has_left: | ||
| root.left = self.buildTree( | ||
| preorder[1 : root_index_at_inorder + 1], | ||
| inorder[:root_index_at_inorder], | ||
| ) | ||
|
|
||
| has_right = root_index_at_inorder != len(inorder) - 1 | ||
| if has_right: | ||
| root.right = self.buildTree( | ||
| preorder[root_index_at_inorder + 1 :], | ||
| inorder[root_index_at_inorder + 1 :], | ||
| ) | ||
|
|
||
| return root | ||
|
|
||
|
|
||
| # @lc code=end |
39 changes: 39 additions & 0 deletions
39
problems/105.construct-binary-tree-from-preorder-and-inorder-traversal/step2.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # | ||
| # @lc app=leetcode id=105 lang=python3 | ||
| # | ||
| # [105] Construct Binary Tree from Preorder and Inorder Traversal | ||
| # | ||
|
|
||
| # @lc code=start | ||
| # 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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: | ||
| root_val = preorder[0] | ||
| root = TreeNode(preorder[0]) | ||
| root_index_at_inorder = inorder.index(root_val) | ||
|
|
||
| has_left = root_index_at_inorder != 0 | ||
| if has_left: | ||
| root.left = self.buildTree( | ||
| preorder[1 : root_index_at_inorder + 1], | ||
| inorder[:root_index_at_inorder], | ||
| ) | ||
|
|
||
| has_right = root_index_at_inorder != len(inorder) - 1 | ||
| if has_right: | ||
| root.right = self.buildTree( | ||
| preorder[root_index_at_inorder + 1 :], | ||
| inorder[root_index_at_inorder + 1 :], | ||
| ) | ||
|
|
||
| return root | ||
|
|
||
|
|
||
| # @lc code=end | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
最初に preorder/inorder が空かどうかをチェックすることで、少しシンプルにできそうです。