Skip to content

108 convert sorted array to binary search tree#24

Open
kitano-kazuki wants to merge 5 commits intomainfrom
108-convert-sorted-array-to-binary-search-tree
Open

108 convert sorted array to binary search tree#24
kitano-kazuki wants to merge 5 commits intomainfrom
108-convert-sorted-array-to-binary-search-tree

Conversation

@kitano-kazuki
Copy link
Copy Markdown
Owner

* rootを返す
* 計算量を考える
* 計算量をT(N)とする
* T(N) = T(N/2) + T(N/2) = T(N / 2^2) + ... + T(N / 2^2)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fyi] 細かい話ですが、rootノードの作成や部分配列の中央値へのアクセスなど定数時間の処理が含まれるため、漸化式は以下のようになります。
$$T(N) = 2T(N/2) + O(1)$$

最終的なオーダー $T(N) = O(N)$ は変わりませんが、代入法で上界を証明する際には注意が必要です。
$T(N)\le cN$ なる仮定を代入すると、
$$T(N) \le cN + d$$
となり( $d$$O(1)$ の係数)、 $cN+d \le cN$ なる 定数 $c$ が存在せずに証明が回りません。代わりに定数 $c_0, c_1$ を使ったより強い評価
$T(N) \le c_1 N- c_0$ の仮定が必要です。 cf

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oだからざっくりでいいだろうとしていましたが, 厳密に考えると引っかかる点が多そうでしたね。
今後気をつけて使用するようにします。ありがとうございます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

細かい話は必要な時に引き出しから出せればよいと思います。
見積もりなので、意識的にどこを捨ててるかを分かれば良いのではないでしょうか。

right_nums = nums[mid_idx + 1:]
root_node.left = self.sortedArrayToBST(left_nums)
root_node.right = self.sortedArrayToBST(right_nums)
return root_node
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「ルートノードの左右の子を一旦仮り置き(None)で作ります。部下に仕事を渡します。結果からルートノードの左右の子を上書きして返します。」
よりかは、
「部下に作成をお願いした木の根を左右の子に、中央値を値にしたノードを根として作成して返します。」
の方が個人的にはわかりやすいと思います

return TreeNode(
    val=nums[mid_index],
    left=self.sortedArrayToBST(nums[:mid_index],
    right=self.sortedArrayToBST(nums[mid_index + 1:],
)

一つの関心に関係するものがあつまっているほうが、理解するのに必要なワーキングメモリが少なくなるからなんでしょうね。
もちろん集めて肥大化したら理解しにくくなるので、トレードオフを見ることも必要ではあると思います。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left_nums, right_nums を使ってもいいと思います。上はスマホで打ったので横着しました

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自分もそちらの方がわかりやすいと思いました。

class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
root = TreeNode()
frontier = [(0, len(nums) - 1, root)]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frontier は幅優先探索で未探索の最前線のノードの集合を表す際に使うように思います。深さ優先探索ではあまり使わない印象があります。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

横から失礼します。深さ優先探索でもfrontierを使用している例はあるようで、個人的にはこのままで良いのではないかと思います。
https://github.com/aimacode/aima-python/blob/master/search.py#L206

# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
def sortedArrayToBST_with_range(nums, left, right):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loweCamel と lower_snake が混ざっている点に違和感を感じました。自分なら build 等、シンプルな関数名を付けると思います。

mid_idx = len(nums) // 2
root_node = TreeNode(nums[mid_idx])
left_nums = nums[:mid_idx]
right_nums = nums[mid_idx + 1:]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PEP8 によると、スライスを作るとき、 + 演算子の両側にはスペースを空けないことになっているようです。
https://peps.python.org/pep-0008/#pet-peeves

なお、このスタイルガイドは“唯一の正解”というわけではなく、数あるガイドラインの一つに過ぎません。チームによって重視される書き方や慣習も異なります。そのため、ご自身の中に基準を持ちつつも、最終的にはチームの一般的な書き方に合わせることをお勧めします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants