diff --git a/108. Convert Sorted Array to Binary Search Tree.md b/108. Convert Sorted Array to Binary Search Tree.md new file mode 100644 index 0000000..470908b --- /dev/null +++ b/108. Convert Sorted Array to Binary Search Tree.md @@ -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]: + if not 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)) +``` \ No newline at end of file