繰り返しで二分探索木に新しい値を葉として足す

二分探索木に​新しい​値を​足し、​足した​あとの​木を​返します。​大小で​左右へ​進んで​空いた所を​探し、​そこへ​葉としてつなぐ​練習です。

海外で定番の問題リスト 4 本には入っていません

問題

二分探索木の根 root と、木にまだ無い整数 val を受け取ります。val を持つ節を新しく作って木に足し、足したあとの木の根を返す関数を書いてください。

  • 二分探索木では、どの節でも、左の部分木の値はすべてその節より小さく、右の部分木の値はすべてその節より大きくなっています
  • 足し方は 1 つに決めます。根から、val が節より小さければ左、大きければ右へ進み、子の無い所に出たら、そこへ新しい節を葉としてつなぎます。木の形を組み替えてはいけません
  • 各節は val、left、right を持ちます。Go の節は TreeNode で、Val、Left、Right です。新しい節は、Python では TreeNode(val)、JavaScript では new TreeNode(val) で作れます。Go では TreeNode を作り、そのアドレスを使います (解答の初めの数行を見てください)
  • root が空の木のこともあります。そのときは、val の節 1 つだけの木を返します
  • 節の数は 0 以上 500 以下です。値はどれも違い、val も含めて -100000000 以上 100000000 以下です

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

入力と出力の例

例 1

50 は 40 より大きいので右の 60 へ進み、60 より小さいので 60 の左の空きに入ります。

入力

root = [40, 20, 60, 10, 30]
val = 50

出力

[40, 20, 60, 10, 30, 50]

例 2

同じ木に 35 を足します。40 の左、20 の右と進み、30 の右の空きに入ります。

入力

root = [40, 20, 60, 10, 30]
val = 35

出力

[40, 20, 60, 10, 30, null, null,
  null, null, null, 35]

例 3

空の木です。新しい節が、そのまま根になります。

入力

root = []
val = 3

出力

[3]

面接での聞かれ方

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

  • 「二分探索木に値を 1 つ足して、根を返してください」
  • 「足し方は何通りもありますが、いちばん素直な形でかまいません」と言われ、葉として足す形を選べるかを見られます
  • 書き終えたあとに「再帰でも書けますか?」「同じ値を何度も足すと、木はどうなりますか?」と聞かれます

木の問題では、どの位置につなぐかを先に口で言っておくと、聞き手も追いやすくなります。

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

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


# 「実行」を押すと、この行の結果が出ます
# build_tree は、例と同じ並びから木を組みます
print(insert_bst(build_tree([40, 20, 60, 10, 30]), 50))

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