再帰で二分探索木の決まりを確かめる

二分木が​二分探索木の​決まりを​守っているかを​返します。​親と​子だけを​比べる​落とし穴を​避け、​各節に​入って​よい​値の​範囲を​上から​渡していく​練習です。

海外で定番の問題リスト 4 本のうち 4 本に入っています (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150)

問題

二分木の根 root を受け取ります。この木が二分探索木なら真、そうでなければ偽を返す関数を書いてください。ここでの二分探索木は、どの節についても次が成り立つ木です。

  • 左の部分木にある値は、どれもその節の値より小さい
  • 右の部分木にある値は、どれもその節の値より大きい
  • 同じ値は許しません。同じ値が 2 つあれば偽です

各節は val (値)、left (左の子)、right (右の子) を持ちます。子が無いところは、Python では None、JavaScript では null、Go では nil です。Go の節は TreeNode で、Val、Left、Right と大文字で始まります。節の数は 1 以上 500 以下、値はどれも -2147483648 以上 2147483647 以下です。

例では、木を上の段から左の順に読んだ値の並びで書きます。子が無いところは null です。

入力と出力の例

例 1

根が 8、左に 3 とその下の 1 と 6、右に 12 とその下の 10 と 15 がある木です。どの節も決まりを守っています。

入力

root = [8, 3, 12, 1, 6, 10, 15]

出力

true

例 2

3 の右の子が 9 です。親の 3 より大きいので親子だけを見ると守っていますが、9 は根 8 の左の部分木にあるのに 8 より大きいので偽です。

入力

root = [8, 3, 12, 1, 9]

出力

false

例 3

左の子が根と同じ 5 です。同じ値は許さないので偽です。

入力

root = [5, 5]

出力

false

面接での聞かれ方

面接では、短く次のように渡されることが多いです。

  • 「この二分木が、正しい二分探索木かどうかを判定してください」
  • 親と子だけを比べる書き方を出すと、例 2 のような木を示して「これはどうなりますか?」と聞かれます
  • 書き終えたあとに「中順 (左、自分、右の順) にたどる書き方でも書けますか?」「同じ値を左に許す決まりならどこを変えますか?」と広げて聞かれます

同じ値を許すかどうかは決まりによって違うので、最初に確かめて口に出しておきます。

アルゴリズムのチートシートの「再帰と木」に、​この​型の​要点を​表と​コードで​まとめています。

main.py
def is_search_tree(root):
    # root の節は val、left、right を持ちます。空きは None です
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
# build_tree は、例と同じ並びから木を組みます
print(is_search_tree(build_tree([8, 3, 12, 1, 6, 10, 15])))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します