-
Notifications
You must be signed in to change notification settings - Fork 0
108. Convert Sorted Array to Binary Search Tree #26
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
base: main
Are you sure you want to change the base?
Conversation
class Solution: | ||
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: | ||
def to_bst(begin: int, end: int) -> Optional[TreeNode]: | ||
if begin == end: |
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.
個人的には、二分探索の終了条件は不等号もつけた方が分かりやすいと思います。
趣味の範囲かもしれません。
def to_bst(begin: int, end: int) -> Optional[TreeNode]: | ||
if begin == end: | ||
return None | ||
mid = (begin + end) // 2 |
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.
単語は略さない方が良いと思いました。
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.
何となくmidは市民権を得ている感覚があったのですが、微妙ですかね。
わりとしっくり来ているのでどうしようかな...もうちょっと試して決めてみようかと思います
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.
mid という形容詞はありますね。
https://www.merriam-webster.com/dictionary/mid
if not nums: | ||
return None | ||
sentinel = TreeNode() | ||
parent_with_range_stack = [(sentinel, 0, len(nums), True)] |
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.
最初にsentinelの左側にnodeをくっつけるのがほんの少しだけ気になりました。
これやるなら最初の処理をwhileの外で行うとかですかね。
stack.append(('back', node_ref, left_node_ref, right_node_ref, begin, end)) | ||
stack.append(('go', left_node_ref, Box(None), Box(None), begin, mid)) | ||
stack.append(('go', right_node_ref, Box(None), Box(None), mid + 1, end)) | ||
node_ref.value.left = left_node_ref.value |
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.
ここの処理が行きがけでも行われるのが少し違和感があります。
個人的には
行き→下にTreeNodeを作るようにたのむ
帰り→下で作ったTreeNodeを繋ぎ合わせる
この方法のほうが再帰との対応が良いかと思いました。
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.
すみません、あまりイメージが湧かず...質問させてください。
ここの処理が行きがけでも行われるのが少し違和感があります。
これはどこの部分になるでしょうか?
行き→下にTreeNodeを作るようにたのむ
帰り→下で作ったTreeNodeを繋ぎ合わせる
もし良ければでいいんですが、コードがどんな感じになるか書いていただけないでしょうか?
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.
イメージこんな感じです
まあelseを足しただけですが...
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
root_ref = Box(None)
stack = [('go', root_ref, Box(None), Box(None), 0, len(nums))]
while stack:
go_back, node_ref, left_node_ref, right_node_ref, begin, end = stack.pop()
if go_back == 'go':
if begin == end:
continue
mid = (begin + end) // 2
node_ref.value = TreeNode(nums[mid])
stack.append(('back', node_ref, left_node_ref, right_node_ref, begin, end))
stack.append(('go', left_node_ref, Box(None), Box(None), begin, mid))
stack.append(('go', right_node_ref, Box(None), Box(None), mid + 1, end))
else: #go_back == 'back'
node_ref.value.left = left_node_ref.value
node_ref.value.right = right_node_ref.value
return root_ref.value
このelseがないとgo_back === 'go'
のときも左右のノードをつなげる処理が行われていて、行きと帰りで違う処理をしている理由があまりないかなと思いました。
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 go_back == 'go'
のブロックの最後にcontinue付けてるつもりでいました。
たしかにおっしゃる通り今のコードだとgoの処理でも左右につなげてますね、失礼しました 🙇
root_ref = Box(None) | ||
stack = [('go', root_ref, Box(None), Box(None), 0, len(nums))] | ||
while stack: | ||
go_back, node_ref, left_node_ref, right_node_ref, begin, end = stack.pop() |
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.
自分だけかもしれませんが、refが何を参照しているかが少し戸惑ったのですが、Boxを利用される場合はよくある書き方でしょうか?node, left_child, right_childとかでも良い気がしました。見当違いでしたらすみません。
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.
よくあるのかは分からないんですが、個人的にはPythonのような動的型付け言語で _ref
の接尾辞を書かずnodeみたいに書くと、TreeNodeなのかTreeNodeを指すコンテナなのかが分からず書きにくくなる印象がありました。
スタックに直した版。node_and_ranges_stackにappendする値を間違えており (right側で(node.right, mid, end)を積むようにしていた)、図を書くまで何が問題か分からず時間がかかった。 | ||
こういう勘違いはこのアルゴリズムで何をしているかきちんと分かっており言語化できればあまり起こらないと思うので、理解不足なのだろう。 | ||
|
||
node_and_ranges_stackはもう少しいい名前があるかも。Pythonでは問題ないがendはちょっとキーワード感あるかもしれない? |
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.
冗長に感じる場合、_stackは省略しても良いのかなと思いました。(好みの問題かもです。)
https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/