24. Convert Sorted Array to Binary Search Tree
読了目安 約2分
Tree / LC 108 (Easy) — ソート済み配列から高さ平衡な BST を作る。
この章の目次
問題
LeetCode 108. Convert Sorted Array to Binary Search Tree(Easy / カテゴリ: Tree)
昇順にソートされた整数配列 nums を、高さ平衡な二分探索木に変換して根を返します。
二分探索木(BST)は、どのノードでも「左の部分木のすべての値 < ノードの値 < 右の部分木のすべての値」が成り立つ二分木です。
高さ平衡とは、すべてのノードで左右の部分木の高さの差が 1 以下という条件です。
答えは一意ではないため、このページのテストは「中間順走査がソート列と一致する」「すべてのノードで左右の部分木の高さの差が 1 以下」の 2 つの性質で採点します。
考え方
ヒント 1
BST を中間順(左→自分→右)で走査すると昇順の列になります。 ソート済み配列をその走査結果と見なすと、根に選ぶべき要素が決まります。
ヒント 2
配列の中央の要素を根にすると、左半分と右半分の要素数の差が 1 以下になり、高さ平衡が保てます。 左半分から左の部分木を、右半分から右の部分木を、同じ手順の再帰で作ります。
Swift 実装のポイント
- 部分配列を
Array(nums[lo...mid])のように切り出すとコピーが発生します。添字の範囲を引数に取る再帰にすると O(N) で済みます。 - メソッドの中に
func build(_ lo: Int, _ hi: Int) -> TreeNode?を定義すると、numsを引き回さずに書けます。 - 中央の添字は
(lo + hi) / 2です。lo > hiが空の部分木のベースケースです。
模範解答
class Solution {
func sortedArrayToBST(_ nums: [Int]) -> TreeNode? {
func build(_ lo: Int, _ hi: Int) -> TreeNode? {
if lo > hi { return nil }
let mid = (lo + hi) / 2
let node = TreeNode(nums[mid])
node.left = build(lo, mid - 1)
node.right = build(mid + 1, hi)
return node
}
return build(0, nums.count - 1)
}
}計算量: O(N)。要素 1 個につきノードを 1 個作ります。