Swift教室 Swift と競技プログラミングの教室

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 が空の部分木のベースケースです。
模範解答
Swift
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 個作ります。