問題
二分探索木のroot と、p、q をp のq の
- 二分探索木では、
どの 節でも、 左の 部分木の 値は すべて その 節より 小さく、 右の 部分木の 値は すべて その 節より 大きくなっています - 節は
自分 自身の 子孫にも 数えます。 片方の 節が もう 片方の 祖先なら、 上に ある方が答えです - 各節は
val、left、rightを持ちます。 Go の 節は TreeNodeで、Val、Left、Rightです - 節の
数は 2 以上 500 以下です。 値は どれも 違い、 -1000000000 以上 1000000000 以下です。 pとqは違う値で、 どちらも 必ず木の 中に あります。 pとqのどちらが 小さいかは 決まっていません
例では、null です。
入力と出力の例
例 1
5 と 15 は、
入力
root = [20, 10, 30, 5, 15, 25,
40]
p = 5
q = 15出力
10例 2
3 は 2 の
入力
root = [8, 4, 12, 2, 6, 10, 14,
1, 3]
p = 6
q = 3出力
4例 3
40 は 30 の
入力
root = [50, 30, 70, null, 40]
p = 30
q = 40出力
30面接での聞かれ方
面接では、
- 「二分探索木で、
2 つの 値の 共通の 祖先を 返してください」 - ふつうの
二分木と 同じ 書き方 (両側を 全部 たどる ) を 答えると、 「二分探索木である ことを 使えますか?」と 聞き返されます - 「片方が
もう 片方の 祖先の ときは どうなりますか?」と、 端の 場合を 口で 確かめられます
ふつうの
アルゴリズムのチートシートの「再帰と木」に、この型の要点を表とコードでまとめています。
まず 考える手順
段 1
まずp までのq までの
段 2
二分探索木のp も q も
段 3
小さい方とp と q は
解答
Python
Python
def common_ancestor(root, p, q):
lo = min(p, q)
hi = max(p, q)
node = root
while True:
if hi < node.val:
node = node.left
elif lo > node.val:
node = node.right
else:
return node.valJavaScript
JavaScript
function commonAncestor(
root, p, q
) {
const lo = Math.min(p, q);
const hi = Math.max(p, q);
let node = root;
while (true) {
if (hi < node.val) {
node = node.left;
} else if (lo > node.val) {
node = node.right;
} else {
return node.val;
}
}
}Go
Go
func commonAncestor(
root *TreeNode, p, q int,
) int {
lo, hi := p, q
if lo > hi {
lo, hi = hi, lo
}
node := root
for {
if hi < node.Val {
node = node.Left
} else if lo > node.Val {
node = node.Right
} else {
return node.Val
}
}
}「今のelse に
計算量
- 時間は O(h) です。
h は 木の 高さです。 根から 答えの 節まで、 1 本道を 下るだけです。 木が 片側に 伸びきると h は n に なり、 O(n) です - 使う
記憶は O(1) です。 lo、hi、nodeの 3 つの置き場だけを 使い、 再帰の 呼び出しも 積みません
よく ある間違い
pとqの大小を 決めつける。 pが小さい 方だと 思い込んで p < node.valとq > node.valで分けると、 例 2 のように pの方が 大きい 入力で 道を 間違えます。 先に 小さい方と 大きい方を決めます - 等しい
場合を 下へ 進めてしまう。 <=で比べると、 今の 節が pそのものなのに、 さらに 下へ 進んで 答えを 通り過ぎます。 等しい ときは その 節が答えです - 二分探索木の
決まりを 使わない。 ふつうの 二分木と 同じく 両側を 全部 たどると、 答えは 合いますが O(n) かかり、 面接では 「決まりを使えていない」と 見られます - 節を
返してしまう。 この 問題で 返すのは 節の 値です。 節その ものを 返すと 比べられません
解答を動かした版 Python 3.12.14Node.js 22.23.4Go 1.24.6確認日 2026年10月30日
面接での 話し方の例
書き始める
「ふつうの
二分木なら 両側を たどりますが、 二分探索木なので 大小で 行き先が 決まります。 2 つの 値が どちらも 今の 節より 小さければ 左、 どちらも 大きければ 右へ 進み、 それ以外なら 2 つは ここで 分かれるので、 今の 節が 答えです。 片方が 今の 節と 等しい 場合も ここに 入ります。 時間は 木の 高さ分の O(h)、 記憶は O(1) です。」
書き終えたら、
「例 2 で
たどります。 小さい方は 3、 大きい方は 6 です。 根の 8 は 6 より 大きいので 左の 4 へ 進みます。 4 は 3 より 大きく 6 より 小さいので、 2 つは ここで 左右に 分かれます。 答えは 4 です。」
