アルゴリズムこの記事についてUnion-findに続き、コーディング面接に備える上で大事そうなデータ構造であるセグメント木を勉強したので、セグメント木を使用して解ける問題を解いてみます。セグメント木とは?セグメント木自体の説明は、また他の方のスライドに丸投げします。下記スライドの33ページ目から詳しく説明してあります。Akibawww.slideshare.net要するに、セグメント木とは、配列のある範囲内の最大値だったり最小値だったりという興味のある値を、完全二分木を使って管理するデータ構造です。求めることができます。今回解く問題このセグメント木を使って、今回はLeetCodeの下記の問題を解きます。LeetCode自体の紹介記事はこちら。val)関数でnums[i]をvalに変更することができるとする。https://leetcode.com/problems/range-sum-query-mutable/配列numはupdate関数以外で変更されることはなく、和を求める関数とupdate関数は均等に呼ばれると仮定してよいそうです。8というような動きになります。今回実装すべきsumRangeという、指定された範囲内の合計を求める関数は、セグメント木の考え方をそのまま適用することができます。上で紹介したスライドでは、セグメント木の各ノードで最小値を保持していましが、その代わりに合計値を保持するようにするだけでOKです。セグメント木は完全二分木なので、ヒープを使うと扱いやすそうなので、ヒープを使って実装してみます。実装これが私の実装したコードになります。コメントを山のようにつけたのでコードを追っていくとわかっていただけるのではないでしょうか。スライドに紹介されていたように、始点はinclusive、終点はexclusiveで実装しているので、実装は比較的簡潔になっているかと思います。2の累乗の中でn以上の最小のものを求める。実装上扱いやすいため。セグメント木の初期化。葉ノードを与えられた配列で初期化する。1番目以降の要素が葉ノードとなる。その後は葉から根に向かって順にノードを初期化していく。各ノードは2つの子の合計値を持つので、根から初期化しないように注意。