幅優先探索 (BFS) で 二分木を 右から 見た ときに 見える 節を並べる
二分木を
海外で定番の問題リスト 4 本には入っていません
問題
二分木のroot を
- 右から
見えるのは、 それぞれの 段 (根からの 深さが 同じ節の 集まり ) で いちばん右に ある節です - いちばん右の
節は 右の 子とは 限りません。 その 段に 左の 子しか 無ければ、 その左の 子が見えます - 各節は
val(値)、left(左の子)、 right(右の子) を 持ちます。 子が 無い ところは、 Python では None、JavaScript では null、Go では nilです。Go の 節は TreeNodeで、Val、Left、Rightと大文字で 始まります - 木が
空の ときは 空の 並び []を返します - 節の
数は 0 以上 100 以下、 値は どれも -100 以上 100 以下です
例では、null です。
入力と出力の例
例 1
根が 8、
例 2
いちばん下の
例 3
空の
面接での聞かれ方
段ごとに
- 「二分木を
右から 見た ときに 見える 節を、 上から 順に 返してください」 - 二分木を
段ごとに 読む問題 (この 一覧の tree-levels) の 続きとして 出される ことが よくあります - 「深さ優先探索 (DFS) でも
書けますか?」と 聞かれる ことがあります。 右の 子を 先に たどり、 その 深さに 初めて 来た ときの 節を 拾えば 同じ 答えになります
ミドルの
ヒント
まだ開いていません
付箋は 4 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3
ヒント 4答えに近い
アルゴリズムのチートシートの「再帰と木」に、
関わる学び
再帰は、
まず 考える手順
段 1
まず
段 2
右から
段 3
左から
段 4
木が
解答
Python
Python
def right_side_view(root):
out = []
lv = [root] if root else []
while lv:
out.append(lv[-1].val)
kids = []
for n in lv:
kids.append(n.left)
kids.append(n.right)
lv = [k for k in kids
if k]
return outJavaScript
JavaScript
function rightSideView(root) {
const out = [];
if (root === null) {
return out;
}
let level = [root];
while (level.length > 0) {
const next = [];
for (const node of level) {
if (node.left) {
next.push(node.left);
}
if (node.right) {
next.push(node.right);
}
}
out.push(level.at(-1).val);
level = next;
}
return out;
}Go
Go
func rightSideView(
root *TreeNode,
) []int {
out := []int{}
if root == nil {
return out
}
level := []*TreeNode{root}
for len(level) > 0 {
next := []*TreeNode{}
for _, n := range level {
if n.Left != nil {
next = append(
next, n.Left)
}
if n.Right != nil {
next = append(
next, n.Right)
}
}
last := level[len(level)-1]
out = append(out, last.Val)
level = next
}
return out
}キューの
計算量
- 時間は O(n) です。
どの 節も 1 回キューに 入り、 1 回取り出されます - 使う
記憶は O(w) です。 w は いちばん節の 多い 段の 節の 数で、 キューに 1 段分が 入ります。 いちばん悪いと O(n) です
よく ある間違い
- 右の
子だけをたどる。 例 2 の 6 のように、 左側の 枝に しか節が 無い段で 見落とします - 段の
区切りを 付けずに キューを回す。 取り出すたびに 答えに 足すと、 全部の 節が 入ります。 段の 数を 先に 数えて おき、 その 数だけ 取り出した ところで 1 段と見ます - 子を
右、 左の 順に 入れて、 最後の 節を拾う。 入れる 順を 逆に したなら、 拾うのは 段の 最初の 節です。 入れる 順と 拾う 位置を そろえます - 空の
木で 根の 値を読む。 例 3 のように rootが空なら、 何も 読まずに 空の 並びを返します
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「右から
見えるのは 各段の いちばん右の 節なので、 右の 子だけを たどるのではなく、 木を 段ごとに 読みます。 キューで 1 段ずつ左から 右へ 取り出し、 段の 最後に 取り出した 節の 値を 答えに 足します。 時間は O(n)、 記憶は いちばん 広い 段の 分です。」
書き終えたら、
「例 2 では、
1 段目は 1 だけなので 1 を 足します。 2 段目は 2、 3 で、 最後の 3 を 足します。 3 段目は 2 の 左の 子の 6 だけで、 それが 最後なので 6 を 足し、 1、 3、 6 です。 右の 子だけを たどると 3 で 止まり、 6 を 見落とします。」