-
Notifications
You must be signed in to change notification settings - Fork 0
Add 108. Convert Sorted Array to Binary Search Tree.md #24
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?
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,92 @@ | ||
# step 1 | ||
|
||
再帰で作ることを思いついた。 | ||
再帰の深さは最大で、log_2(10^4) = 4 * log_2(10) = 4 * (1 + log_2(5)) < 4 * 4 = 16。 | ||
|
||
ノードの数をnとして、 | ||
- time complexity: O(n log n) | ||
- space complexity: O(n) | ||
|
||
ノード数nの時の実行時間をT(n)とすると、半分に分けた問題を二つ解く + スライスのコピーで | ||
T(n) = 2*T(n/2) + nとなる(merge sortとかと同じ形)。 | ||
|
||
```python | ||
class Solution: | ||
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: | ||
if not nums: | ||
return None | ||
|
||
middle = len(nums) // 2 | ||
left = self.sortedArrayToBST(nums[:middle]) | ||
right = self.sortedArrayToBST(nums[middle + 1:]) | ||
return TreeNode(val=nums[middle], left=left, right=right) | ||
``` | ||
|
||
# step 2 | ||
- https://github.com/colorbox/leetcode/pull/38/files | ||
- ダブルポインタを使った非再帰の解法あり | ||
- https://github.com/SuperHotDogCat/coding-interview/pull/40/files#r1770559848 | ||
- > スライスを作るとコピーが発生し、処理が重くなる | ||
- indexを追跡して行った方が処理が重くならない | ||
- https://github.com/python/cpython/blob/c9932a9ec8a3077933a85101aae9c3ac155e6d04/Objects/listobject.c#L656 | ||
- 新しいreferenceをiterateしながら作る | ||
|
||
ほかにもいくつか過去のプルリクを見たがあまり解法に幅がないように感じた。 | ||
|
||
stackを使った解法。step 1の時点で再帰を使ったDFSで書けているので、これも思いつきたかった。 | ||
- time complexity: O(n) | ||
- space complexity: O(n) | ||
```python | ||
class Solution: | ||
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: | ||
if not nums: | ||
return None | ||
|
||
root = TreeNode() | ||
stack = [(root, 0, len(nums))] | ||
while stack: | ||
node, left, right = stack.pop() | ||
middle = (left + right) // 2 | ||
node.val = nums[middle] | ||
if left < middle: | ||
node.left = TreeNode() | ||
stack.append((node.left, left, middle)) | ||
if middle + 1 < right: | ||
node.right = TreeNode() | ||
stack.append((node.right, middle + 1, right)) | ||
return root | ||
``` | ||
|
||
スライスを作らない再帰 | ||
- time complexity: O(n) (T(n) = 2*T(n/2) + 1) | ||
- space complexity: O(n) | ||
```python | ||
class Solution: | ||
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: | ||
def index_range_to_BST(left: int, right: int) -> Optional[TreeNode]: | ||
if not left < right: | ||
return None | ||
|
||
middle = (left + right) // 2 | ||
left = index_range_to_BST(left, middle) | ||
right = index_range_to_BST(middle + 1, right) | ||
return TreeNode(nums[middle], left, right) | ||
return index_range_to_BST(0, len(nums)) | ||
``` | ||
|
||
# step 3 | ||
step 2ではinner関数ないでleft, rightを書き換えていたので書き換えない形でも書いた。 | ||
|
||
```python | ||
class Solution: | ||
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: | ||
def index_range_to_BST(left: int, right: int) -> Optional[TreeNode]: | ||
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. helperみたいな命名もありかなと思いました |
||
if not left < right: | ||
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. 僕はnot使わず書いてましたが、not 使うこちらの方が直感に近いかもですね。 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. ありがとうございます。二分探索もそうですが、これとかも、区間の取り方と成立不成立によって'='がついたりつかなかったりしてややこしいので、notを入れて統一するのが好みかもしれません 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. わかります。探索アルゴリズムのグリッド範囲外判定とかも not でやりたい気持ちです。 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. ここらへんは趣味かと思います。私は、left >= right と左が大きいときには否定的な意味としています。 |
||
return None | ||
|
||
middle = (left + right) // 2 | ||
left_node = index_range_to_BST(left, middle) | ||
right_node = index_range_to_BST(middle + 1, right) | ||
return TreeNode(nums[middle], left_node, right_node) | ||
return index_range_to_BST(0, len(nums)) | ||
``` |
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.
下でコメントされていますが、int型の引数leftをTreeNodeとしても用いるのはあまり良くないと思います。